Reputation: 45
I am trying to receive data asynchronously using asyncio sock_recv. I am sending data from a server to two different ports with different speeds : data X every 10ms and data Y every 100ms.
When using blocking socket recvfrom function i'd receive X and Y every 100ms since it blocks in the Y recvfrom, so i tried using asyncio so that while Y is waiting i would receive 10 X and then one Y.
To do that i wrote those functions :
async def recv_data(socket):
data = await loop.sock_recv(socket, 2048)
print(len(data))
async def main():
UDP_IP = "192.168.1.10"
RAW_PORT = 125
MCU_PORT = 126
SERVER_PORT = 5001
SOCK_RAW = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
SOCK_RAW.bind(('', RAW_PORT))
SOCK_MCU = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
SOCK_MCU.bind(('', MCU_PORT))
while True :
await asyncio.gather(recv_data(SOCK_RAW), recv_data(SOCK_MCU))
while True:
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
But what i get with this is not quite what i expect :
576
540
576
540
576
540
540
576
540
576
576
540
576
540
576
540
540
576
540
576
Am i not using the asyncio package in a good way ?
Upvotes: 1
Views: 1748
Reputation: 149
import asyncio
import socket
async def recv_data(c_socket):
while True : # also add an interuption logic as break the loop if empty string or what you have there
data = await loop.sock_recv(c_socket, 2048)
if data == '':
break
print(len(data))
def create_socket(port, host='localhost'):
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server.bind(('', port))
server.setblocking(False)
return server
async def main():
UDP_IP = "192.168.1.10"
RAW_PORT = 125
MCU_PORT = 126
SERVER_PORT = 5001
servers = [
create_socket(port) for port in { RAW_PORT, MCU_PORT }
]
listen_connections = [
loop.create_task( recv_data(server) ) for server in servers
]
await asyncio.gather(*listen_connections)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
The problem was in your while loop recv_data is receiving data only once and waits when it will be called one more time, and a job at 100ms socket is not finished means while loop still stays at the same iteration with a waiting time of 100ms.
I edited the code a bit, I mist watch sockets was not set to nonblocking mode thats why you getting an only response from one socket
Upvotes: 1