尽管传输存在,但 Python AsyncIO 由于缺少传输而无法创建协议(protocol)

标签 python asynchronous python-asyncio

我正在尝试使用 AsyncIO 的 asyncio.protocol 编写一个代理服务器,这似乎在很大程度上起作用。但我收到一个错误,这让我非常困惑。

我的代码如下所示:

import asyncio
import socket

users = {}

class UserConnection(object):
    def __init__(self, client_socket, proxy_socket, peername):
        self.client_socket = client_socket
        self.proxy_socket = proxy_socket
        self.peername = peername

class ClientProxyProtocol(asyncio.Protocol):
    def __init__(self):
        self.transport = None
        self.session = None
        server_connection = loop.create_connection(
                                lambda: ProxyForwardProtocol, 
                                host="127.0.0.1", 
                                port=25575)
        task = loop.create_task(server_connection)
        task.add_done_callback(self.handle_proxy_connection)

    def connection_made(self, transport):
        # Get peername, client socket and create proxy socket
        peername = transport.get_extra_info('peername')
        client_socket = transport.get_extra_info('socket')
        # Get session object for a user and add in dict keyed of proxy socket
        self.session = UserConnection(client_socket, None, peername)
        print('Connection from {}'.format(peername))
        self.transport = transport

    def handle_proxy_connection(self, task):
        trans, proto = task.result()
        proxy_socket = trans.get_extra_info("socket")
        self.session.proxy_socket = proxy_socket
        users[proxy_socket] = self.session
        print(trans,"\n",proto)

    def data_received(self, data):
        message = str(data) 
        print('Data received: {!r}'.format(message))

    def connection_lost(self, exc):        
        print('Close the client socket')
        self.transport.close()


class ProxyForwardProtocol(asyncio.Protocol):
    def __init__(self,transport):
        self.transport = transport

    def connection_made(self, transport):
        proxy_socket = transport.get_extra_info("socket")
        print("HELLO")
        self.transport = transport

    def connection_lost(self, exc):
        print("closing forward connection")
        self.transport.close()

loop = asyncio.get_event_loop()
# Each client connection will create a new protocol instance
coro = loop.create_server(ClientProxyProtocol, '127.0.0.1', 25565)
server = loop.run_until_complete(coro)

# Serve requests until Ctrl+C is pressed
print('Serving on {}'.format(server.sockets[0].getsockname()))
try:
    loop.run_forever()
except KeyboardInterrupt:
    pass

# Close the server
server.close()
loop.run_until_complete(server.wait_closed())
loop.close()

运行此脚本在某种程度上工作得很好,它接受新连接并启动新的协议(protocol)实例,但在尝试与我的目标服务器建立协议(protocol)连接后会产生以下错误。它会产生以下错误:

Exception in callback ProxyForwardProtocol.connection_made(<_SelectorSoc...e, bufsize=0>>) at .\asyncproto.py:53        
handle: <Handle ProxyForwardProtocol.connection_made(<_SelectorSoc...e, bufsize=0>>) at .\asyncproto.py:53>             
Traceback (most recent call last):                                                                                        
File "C:\Users\Huhn\AppData\Local\Programs\Python\Python36-32\lib\asyncio\events.py", line 126, in _run                   
self._callback(*self._args)                                                                                         
TypeError: connection_made() missing 1 required positional argument: 'transport'

我的问题如下:句柄显示connection_made方法接受SelectorSocketTransport,我认为它是一种传输,但仍然说它缺少传输。这对我来说毫无意义。

如果有人能告诉我我的错误在哪里,我将非常感激,因为我还没有找到任何有类似问题的人,而且我有点陷入困境。如果我对代理有任何架构上的误解,请随时指出。我这样做是为了进行教学练习,这就是为什么我不使用可能存在的第三方替代方案的原因。

谢谢

最佳答案

您似乎刚刚在 ClientProxyProtocol.__init__() 中犯了一个拼写错误.

create_connection第一个参数必须是可调用的,它返回 Protocol 对象,而不是您的 (lambda: ProxyForwardProtocol)返回协议(protocol)类

所以,当框架调用connection_made()时,它将传递单个参数(传输),但第一个参数必须是 self 。协议(protocol)是一个类,而不是类实例 -> 方法 connection_made()未绑定(bind) -> self不会自动提供。

删除ProxyForwardProtocol.__init__方法并像这样更改您的调用:

    server_connection = loop.create_connection(
                            ProxyForwardProtocol, 
                            host="127.0.0.1", 
                            port=25575)

关于尽管传输存在,但 Python AsyncIO 由于缺少传输而无法创建协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50546605/

相关文章:

android - 如何使用一个后台服务启动不同的 Activity

python - 类型错误 : A Future or coroutine is required with AWS lambda

Python:脚本的目录

python - 在数据库中搜索第二天格式

c# - C#异步套接字不会返回整页

javascript - 如何使mocha中的 "it"等到 "it"内的 promise 得到解决?

python - `CalledProcessError`模块中是否有 `asyncio`的模拟?

python - 使用 aiohttp.ClientSession() 发出请求时如何为 aiohttp.client 设置日志记录?

python - 在 Plotly 中更改标题字体大小

python - 节点创建期间的 drupal 7 触发脚本