我正在尝试通过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()
我已经阅读了the Python docs example here的有关异步的内容,但是我看到该示例正在使用asyncio
库的内置服务器功能。有人可以帮我将其推广到我的简单TCP服务器吗?我需要自定义解决方案的灵活性(但仍然需要链接的异步服务器的功能)
答案 0 :(得分:2)
如果我的理解正确,那么您正在寻找有关如何使现有TCP代码适应asyncio
的指南。您肯定需要对代码进行重大更改,但是更改应该非常简单。
例如,可以将问题中的代码修改为适用于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())