如何处理TCP客户端套接字在python asyncio中自动重新连接?
我正在使用python asyncio流连接到多个套接字服务器,但是当服务器关闭时,我的代码无法自动重新连接。如何处理TCP客户端套接字在python asyncio中自动重新连接?
我需要的是,当服务器关闭时,我的脚本会尝试每5秒重新连接,直到连接并开始再次解析数据。
import asyncio
server1 = {'host': '192.168.1.51', 'port': 11110}
server2 = {'host': '192.168.1.52', 'port': 11110}
async def tcp_client(host, port, loop):
print('connect to server {} {}'.format(host, str(port)))
reader, writer = await asyncio.open_connection(host, port, loop=loop)
while True:
data = await reader.read(100)
print('raw data received: {}'.format(data))
await asyncio.sleep(0.1)
loop = asyncio.get_event_loop()
try:
for server in [server1, server2]:
loop.run_until_complete(tcp_client(server['host'], server['port'], loop))
print('task added: connect to server {} {}'.format(server['host'], server['port']))
finally:
loop.close()
print('loop closed')
你可以通过简单地在一个try/except
声明循环处理重新连接。另外,asyncio.wait_for可用于设置读取操作的超时。
考虑这个工作的例子:
的所有代码将无法运行import asyncio
async def tcp_client(host, port):
reader, writer = await asyncio.open_connection(host, port)
try:
while not reader.at_eof():
data = await asyncio.wait_for(reader.read(100), 3.0)
print('raw data received: {}'.format(data))
finally:
writer.close()
async def tcp_reconnect(host, port):
server = '{} {}'.format(host, port)
while True:
print('Connecting to server {} ...'.format(server))
try:
await tcp_client(host, port)
except ConnectionRefusedError:
print('Connection to server {} failed!'.format(server))
except asyncio.TimeoutError:
print('Connection to server {} timed out!'.format(server))
else:
print('Connection to server {} is closed.'.format(server))
await asyncio.sleep(2.0)
async def main():
servers = [('localhost', 8888), ('localhost', 9999)]
coros = [tcp_reconnect(host, port) for host, port in servers]
await asyncio.gather(*coros)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
我用你的代码但失败了。当我拔掉我的服务器并再次插入它们时,连接不会再次重新启动。以下是日志:2017-05-26 21:39:54,239 - 连接到服务器10.0.1.68 1100 ... 2017-05-26 21:39:54,240 - 连接到服务器10.0.1.69 1100 ... 2017 -05-26 21:39:54,977 - 收到的原始数据:b'030 1495834968 00.000 00.004 00.010 00.007 00.004 00.000 00.000 00.000 \ n' –
@DesmondChen当您拔下服务器时可能会引发另一个异常,您可以尝试替换'ConnectionRefusedError ''例外''。另外,使用'await asyncio.gather(* coros)'会导致程序在第一个意外的异常停止。 – Vincent
我将“ConnectionRefusedError异常”和“等待asyncio.wait(coros)”更改为“await asyncio.gather(* coros)”。但它仍然不起作用。我认为它卡在异步def tcp_client(主机,端口),并没有引发异常。 –
第一:你不能在使用点符号词典访问项目 - 使用'服务器[“主机”]'或'服务器。获得( '主机')'。 – mhawke
另一个问题是'loop.run_until_complete()'运行直到它完成,即它阻塞。因此,一次只能连接一台服务器。 – mhawke
另一个问题是'tcp_client()'需要检查连接是否关闭。你可以知道当'data'是空字符串时 - 然后从函数返回。 – mhawke