我正在使用asyncio客户端连接,然后断开与服务器的连接。在
如果我连接到同一台计算机上的服务器程序,连接会很好地关闭。添加:当我开始向连接写入数据时,这个连接有时也会发出警告。请参阅下面的第二个代码版本。
如果我连接到本地网络上的设备,我将得到ResourceWarning
的未关闭传输。
如何正确关闭连接?
我在Windows7(64位)上使用Python3.6.0(32位)。在
相关代码:
import asyncio
import logging
import warnings
class ClientConnection(asyncio.Protocol):
def connection_made(self, transport):
self.transport = transport
transport.write_eof() # Send EOF to close connection
def connection_lost(self, exception):
self.transport.close()
super().connection_lost(exception)
def main():
logging.basicConfig(level=logging.DEBUG)
eventLoop = asyncio.get_event_loop()
eventLoop.set_debug(True)
warnings.simplefilter('always', ResourceWarning) # enables ResourceWarning
#co = eventLoop.create_connection(ClientConnection, '127.0.0.1', 7001) # Works without warning
co = eventLoop.create_connection(ClientConnection, '192.168.10.66', 7001) # Gives warning
try:
eventLoop.run_until_complete(co)
finally:
eventLoop.close()
if __name__ == "__main__":
main()
控制台输出:
^{pr2}$我对代码做了以下更改:
connection_lost
中删除{data_received
和{观察结果:
transport.close()
添加到connection_made
中,但它总是会得到OSError: [WinError 10038]
。注意:这可能是另一个问题,所以让我们暂时忽略它,假设我不会这样做。connection_lost
不被调用。为什么?在修改代码:
import asyncio
import logging
import warnings
class ClientConnection(asyncio.Protocol):
def connection_made(self, transport):
logging.debug('connection_made')
self.transport = transport
transport.write(b'1234\r')
transport.write_eof() # Send EOF to close connection
#transport.close() # Cannot close here either, gives 'OSError: [WinError 10038]'
def connection_lost(self, exception):
logging.debug('connection_lost')
super().connection_lost(exception)
def data_received(self, data):
logging.debug('received {} bytes'.format(len(data)))
def eof_received(self):
logging.debug('EOF received')
self.transport.close()
def main():
logging.basicConfig(level=logging.DEBUG)
eventLoop = asyncio.get_event_loop()
eventLoop.set_debug(True)
warnings.simplefilter('always', ResourceWarning) # enables ResourceWarning
#co = eventLoop.create_connection(ClientConnection, '127.0.0.1', 7001) # Works without warning
co = eventLoop.create_connection(ClientConnection, '192.168.10.66', 7001) # Gives warning
try:
eventLoop.run_until_complete(co)
logging.debug('done')
finally:
eventLoop.close()
if __name__ == "__main__":
main()
成功时输出:
...
DEBUG:root:EOF received
DEBUG:root:connection_lost
DEBUG:root:done
DEBUG:asyncio:Close <_WindowsSelectorEventLoop running=False closed=False debug=True>
失败时的输出(注意缺少connection_lost
):
...
DEBUG:root:EOF received
DEBUG:root:done
DEBUG:asyncio:Close <_WindowsSelectorEventLoop running=False closed=False debug=True>
sys:1: ResourceWarning: unclosed <socket.socket fd=240, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto
=6, laddr=('127.0.0.1', 63858), raddr=('127.0.0.1', 7001)>
C:\Program Files (x86)\Python36-32\lib\asyncio\selector_events.py:631: ResourceWarning: unclosed transport <_SelectorSoc
ketTransport closing fd=240>
source=self)
请等待服务器关闭连接,或使用
transport.close()
关闭传输。这也将触发connection_lost
(不要从connection_lost
调用transport.close()
!)公司名称:如果您再尝试一点,您可能还会为您的本地计算机获得一些
ResourceWarning
。例如,尝试在write_eof()
之前添加transport.write(b'hello world!')
,或者使本地服务器响应较慢。在尝试运行循环多一点。下面是一个使用
loop.run_forever()
和loop.stop()
的示例,假设echo server在本地和远程计算机上:相关问题 更多 >
编程相关推荐