Cannot create with async sub process for each socket connection with Python 3.5 asyncio

633 Views Asked by At

I am trying to create a socket server with asyncio where I would asynchronous listen for connection and get each connections incomming message. Howeven I cannot get it working.

Here is my code for server:

import asyncio
import socket, sys
from concurrent.futures import ProcessPoolExecutor

def print_output(csock, loop):
    while 1:
        print('gotcha')
        msg = csock.recv(1024)
        if not msg:
            pass
        else:
            print ("Client send: " + msg)


def s_listen(loop):
    while True:
        (csock, adr) = sock.accept()
        print('start another process')
        asyncio.ensure_future(loop.run_in_executor(executor, print_output, csock, loop))
        print('done')

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) #reuse tcp
sock.bind(('', 12345))
sock.listen(5)
executor = ProcessPoolExecutor()
loop = asyncio.get_event_loop()
listener = asyncio.ensure_future(loop.run_in_executor(executor,s_listen,loop))
print('here')

While this is my code for client

import socket, sys
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('', 12345))
sock.send(b"Hello I'm Client.\r\n")

I can get the function "s_listen" running asynchronously but the code got blocked by "print_output" function.

I am new to asyncio, can anyone help? Thanks!

1

There are 1 best solutions below

0
On

Asyncio provides a coroutine-based API called stream to manage socket clients and servers. Here's a modified version of the tcp echo server from the user documentation:

import asyncio

# Client handler
async def handle_echo(reader, writer):
    while not reader.at_eof():
        data = await reader.read(100)
        message = data.decode().strip()
        print('Client sent: ' + message)
    writer.close()

# Start the server
loop = asyncio.get_event_loop()
coro = asyncio.start_server(handle_echo, '', 12345, 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()

You can test this example with the netcat client:

# Client
$ ncat localhost 12345
hello,
world!

# Server
$ python3.5 server.py
Serving on ('0.0.0.0', 12345)
Client sent: hello,
Client sent: world!