2

I am making a simple server/client chat program in Python. This program should allow for multiple users to connect at once, and then execute their requests concurrently. For this, I am using the asyncio module and sockets.

async def accept_new_connections(socket):
    socket.listen(1)
    while True:
        connection, client_address = sock.accept()
        print("accepted conn")
        asyncio.create_task(accept_commands(socket, connection))

async def accept_commands(socket, connection):
    print("accept cmd started")
    while True:
        # get and execute commands

def main():
    asyncio.run(accept_new_connections(socket))

main()

What I would hope to do is running accept_commands for each of the connections, which would then execute commands concurrently. However, the current code only starts accept_commands for the first connection, and blocks the while loop (the one in accept_new_connections). Any idea what I need to change to have accept_command started for each of the connections instead?

5
  • 1
    You can't call main() before defining it. Commented Nov 23, 2019 at 13:44
  • i have changed the order of the blocks. Commented Nov 23, 2019 at 13:46
  • 1
    That's not helpful for debugging and our understanding of the code. Please correct it and make sure the code produces the problem you are describing. Commented Nov 23, 2019 at 13:48
  • now its in the correct order Commented Nov 23, 2019 at 14:19
  • 1
    Not the answer you are looking for... but, if you are looking for a Flask-like module that is asynchronous I would recommend taking a look at Sanic. It will make your life much easier. Commented Nov 23, 2019 at 15:10

1 Answer 1

3

It is tough to tell because your example does have the implementation of accept_commands, but based on your issue it is likely you need to use the async socket methods on event loop itself so that your coroutine can yield execution and let something else happen.

The below example shows how to do this. This starts a socket on port 8080 and will send back any data it receives back to the client. You can see this work concurrently by connecting two clients with netcat or telnet and sending data.

import asyncio
import socket

socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

socket.bind(('localhost', 8080))
socket.listen(1)
socket.setblocking(False)
loop = asyncio.new_event_loop()

async def main():
    while True:
        connection, client_address = await loop.sock_accept(socket)
        print('connected')
        loop.create_task(accept_commands(connection))


async def accept_commands(connection):
    while True:
        request = await loop.sock_recv(connection, 16)
        await loop.sock_sendall(connection, request)


loop.run_until_complete(main())
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.