向TCP服务器添加异步功能



我正试图通过asyncio库将异步功能添加到我正在使用的简单TCP服务器中。下面是我的foobar示例:

import os
import sys 
import socket 
class Server(object):
def __init__(self, addr):
self.ip, self.port = addr.split(":")
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

def listen(self):
# Listen for incoming requests
self.socket.bind((self.ip, int(self.port)))
print("Listening")
while True:
try:
stream, addr = self.socket.accept()
self._handle_request(stream, addr)
except socket.timeout:
continue 
def _handle_request(self, stream, addr):
# Here I'm handling the request (read and send response)
_mssg = self._recv_data(stream)
pass 
def _recv_data(self, stream):
# unpacking the packed struct that was sent, reading 
# 4-byte struct size first, then using stream.recv()
# until the entire message has been read
return 1

if __name__ == "__main__":
srv = Server("127.0.0.1:9999")
srv.listen()

我已经阅读了这里关于异步的Python文档示例,但我看到这个示例使用了asyncio库的内置服务器功能。有人能帮我把它推广到我的简单TCP服务器上吗?我需要自定义解决方案的灵活性(但仍然需要链接异步服务器的功能(

如果我的理解是正确的,您正在寻找如何将现有TCP代码适应asyncio的指导。您肯定需要对代码进行实质性的更改,但更改应该相当简单。

例如,问题中的代码可以调整为异步,如下所示(未经测试(:

import asyncio, struct
class Server(object):
def __init__(self, addr):
self.ip, self.port = addr.split(":")
async def listen(self):
# Listen for incoming requests
asrv = await asyncio.start_server(self._handle_request, self.ip, int(self.port))
print("Listening")
# on Python 3.6 you would use something like
# while True: await asyncio.sleep(1000)
await asrv.serve_forever()
async def _handle_request(self, reader, writer):
addr = writer.get_extra_info('peername')
# Here I'm handling the request (read and send response)
print('handling', addr)
msg = await self._recv_data(reader)
# ...
async def _recv_data(self, stream):
size_msg = await stream.readexactly(4)
size, = struct.unpack('l', size_msg)
msg = await stream.readexactly(size)
return msg
if __name__ == "__main__":
srv = Server("127.0.0.1:9999")
asyncio.get_event_loop().run_until_complete(srv.listen())

最新更新