使用asyncio和Python3.6,如何构建一个处理/提交多个顺序请求的TCP服务器/客户端?
详情如下:使用asyncio和Python3.6,如何构建一个处理/提交多个顺序请求的TCP服务器/客户端?,python,tcp,python-3.6,python-asyncio,Python,Tcp,Python 3.6,Python Asyncio,详情如下: import asyncio @asyncio.coroutine def handle_echo(reader, writer): data = yield from reader.r
import asyncio
@asyncio.coroutine
def handle_echo(reader, writer):
data = yield from reader.read(100)
message = data.decode()
addr = writer.get_extra_info('peername')
print("Received %r from %r" % (message, addr))
print("Send: %r" % message)
writer.write(data)
yield from writer.drain()
print("Close the client socket")
writer.close()
loop = asyncio.get_event_loop()
coro = asyncio.start_server(handle_echo, '127.0.0.1', 8889, loop=loop)
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()
我适应于连续提出两个请求:
import asyncio
async def tcp_echo_client(loop):
reader, writer = await asyncio.open_connection('127.0.0.1', 8889,
loop=loop)
await make_request(reader, writer, "Foo")
await make_request(reader, writer, "Bar")
print('Close the socket')
writer.close()
async def make_request(reader, writer, message):
print('Send: %r' % message)
writer.write(message.encode())
data = await reader.read(100)
print('Received: %r' % data.decode())
loop = asyncio.get_event_loop()
loop.run_until_complete(tcp_echo_client(loop))
loop.close()
观察到的行为是,客户机获得对第一个请求的响应,但在处理第二个请求之前,套接字已关闭。因此,客户端没有收到对第二个请求的响应
服务器日志:
Received 'Foo' from ('127.0.0.1', 58112)
Send: 'Foo'
Close the client socket
客户端日志:
Send: 'Foo'
Received: 'Foo'
Send: 'Bar'
Received: ''
Close the socket
所需的行为是客户端接收Bar
以响应第二个请求,并在请求之间保持套接字打开
如果我注释掉关闭服务器上的套接字,它会阻塞,这样客户机就不会读取对第一个请求的响应,即使缓冲区本应该由write.drain()
刷新
非常感谢您的指导;提前谢谢。我想我知道了。查看服务器代码:
不会在其事件循环中重复调用asyncio.start\u服务器
。我负责在该处理函数中编写一个循环,对每个请求重用handle\u echo
和reader
writer
- 而不是抛出异常,
在客户端关闭其套接字末端后返回0字节yield from reader.read(100)
import asyncio
@asyncio.coroutine
def handle_echo(reader, writer):
while True:
data = yield from reader.read(100)
if len(data) > 0:
message = data.decode()
addr = writer.get_extra_info('peername')
print("Received %r from %r" % (message, addr))
print("Send: %r" % message)
writer.write(data)
yield from writer.drain()
else:
print("Close the client socket")
writer.close()
break
loop = asyncio.get_event_loop()
coro = asyncio.start_server(handle_echo, '127.0.0.1', 8889, loop=loop)
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()