我有一个阻塞 for 循环,我尝试使用套接字连接到服务器。
我想创建一个非阻塞循环,因为它需要很多时间,例如重叠连接。
这是我的示例代码:
import socket
for _ in range(100):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
s.connect(('', 4444))
最佳答案
正如 MLAlex 所建议的,使用 asyncio 库是有意义的。
这个怎么样,灵感来自asyncio docs :
import asyncio
async def tcp_echo_client(message):
reader, writer = await asyncio.open_connection(
'127.0.0.1', 8888)
print(f'Send: {message!r}')
writer.write(message.encode())
await asyncio.sleep(randint(1,3))
data = await reader.read(100)
print(f'Received: {data.decode()!r}')
print('Close the connection')
writer.close()
await writer.wait_closed()
return data.decode()
async def main():
requests = [
tcp_echo_client(f"msg {i}") for i in range(10)
]
echoes = await asyncio.gather(*requests)
print(echoes)
asyncio.run(main())
例如加上这个回显服务器(需要三秒钟回显一条消息):
import asyncio
async def handle_echo(reader, writer):
data = await reader.read(100)
message = data.decode()
addr = writer.get_extra_info('peername')
print(f"Received {message!r} from {addr!r}")
await asyncio.sleep(3)
print(f"Send: {message!r}")
writer.write(data)
await writer.drain()
print("Close the connection")
writer.close()
async def main():
server = await asyncio.start_server(
handle_echo, '127.0.0.1', 8888)
addr = server.sockets[0].getsockname()
print(f'Serving on {addr}')
async with server:
await server.serve_forever()
asyncio.run(main())
产生:
Send: 'msg 0'
Send: 'msg 1'
Send: 'msg 2'
Send: 'msg 3'
Send: 'msg 4'
Send: 'msg 5'
Send: 'msg 6'
Send: 'msg 7'
Send: 'msg 8'
Send: 'msg 9'
Received: 'msg 0'
Close the connection
Received: 'msg 1'
Close the connection
Received: 'msg 2'
Close the connection
Received: 'msg 3'
Close the connection
Received: 'msg 4'
Close the connection
Received: 'msg 5'
Close the connection
Received: 'msg 6'
Close the connection
Received: 'msg 7'
Close the connection
Received: 'msg 8'
Close the connection
Received: 'msg 9'
Close the connection
['msg 0', 'msg 1', 'msg 2', 'msg 3', 'msg 4', 'msg 5', 'msg 6', 'msg 7', 'msg 8', 'msg 9']
三秒左右,即满足一个请求所需的时间
real 0m3,169s
user 0m0,044s
sys 0m0,084s
如果我们在服务器响应时间上引入一些差异,我们可以看到客户端接收的结果是乱序的。 例如第 10 行:
await asyncio.sleep(randint(3,4))
那么客户端的输出就变成:
(tih1) SO $ time python aio_cnx.py
Send: 'msg 0'
Send: 'msg 1'
Send: 'msg 2'
Send: 'msg 3'
Send: 'msg 4'
Send: 'msg 5'
Send: 'msg 6'
Send: 'msg 7'
Send: 'msg 8'
Send: 'msg 9'
Received: 'msg 1'
Close the connection
Received: 'msg 2'
Close the connection
Received: 'msg 3'
Close the connection
Received: 'msg 7'
Close the connection
Received: 'msg 8'
Close the connection
Received: 'msg 9'
Close the connection
Received: 'msg 0'
Close the connection
Received: 'msg 4'
Close the connection
Received: 'msg 5'
Close the connection
Received: 'msg 6'
Close the connection
['msg 0', 'msg 1', 'msg 2', 'msg 3', 'msg 4', 'msg 5', 'msg 6', 'msg 7', 'msg 8', 'msg 9']
real 0m4,135s
user 0m0,059s
sys 0m0,013s
关于python - python 一次进行更多迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57694298/