I'm currently trying to have a Python script receiving data from two different ports using two different UDP sockets (one socket, one port), initialized as follows:
# socket 1
source1_UDPSock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
source1_UDPSock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
source1_port = 6008
source1_listen_addr = ("",source1_port)
source1_UDPSock.bind(source1_listen_addr)
# socket 2
source2_DPSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
source2_UDPSock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
source2_port = 6009
source2_listen_addr = ("", source2_port)
source2_UDPSock.bind(source2_listen_addr)
The problem comes when I need to retrieve the data received using the following lines:
soc1_data, addr = source1_UDPSock.recvfrom(source1_port)
soc2_data, addr = source2_UDPSock.recvfrom(source2_port)
The code runs normally, but if I don't get any data from the first recvfrom it will block the execution until it gets something. I tried setting both sockets to non-blocking using source1_UDPSock.setblocking(False) in both of them, but it showed to be a bad solution since I had to wait one or two seconds for preventing a BlockingIOError: [WinError 10035] to appear, losing the data that may be being received from the other port.
I tried to use select in the following code after setting both ports to non-blocking:
ready_read, ready_write, exceptional = select.select([source1_UDPSock, source2_UDPSock], [],[], None)
for ready in ready_read:
data_1, addr = source1_UDPSock.recvfrom(source1_port)
data_2, addr = source2_UDPSock.recvfrom(source2_port)
but I had no succeed, as it keep throwing the BlockingIOError 10035.
May the use of multithreading (one thread, one open socket) be the solution for this issue?
Thank you in advance.
Problem solved!
Finally I applied the solution found in this question performing some adaptations. I divided the port listeners into two files and created this script:
import multiprocessing
import subprocess
def worker(file):
subprocess.Popen(['python', file])
if __name__ == "__main__":
files = ['listener1.py', 'listener2.py']
for i in files:
p = multiprocessing.Process(target = worker(i))
p.start()
Each listener needs to perform some specific treatment on the data received (which is different in the two cases), so having both of them separated is OK for me.
Again thank you all!