Reputation: 1447
I'm trying to add async functionality via the asyncio
library, to a simple TCP server that I'm using. Here is my foobar example:
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()
I've read the Python docs example here regarding async, but I'm seeing that this example is using the built-in server functionality of the asyncio
library. Could anyone help me generalize this to my simple TCP server? I need the flexibility of a custom solution (but still the functionality of the linked async server)
Upvotes: 2
Views: 752
Reputation: 155436
If my understanding is correct, you are looking for guidance how to adapt existing TCP code to asyncio
. You will definitely need to make substantial changes to the code, but the changes should be fairly straightforward.
For example, the code from the question could be adapted to asyncio as follows (untested):
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())
Upvotes: 2