JMarc
JMarc

Reputation: 1004

multi-socket in python: asynchronous

I want to use 2 sockets (w/ different ports) on the server side (publisher0 to stream asynchronously data to a single client (subscriber). Each socket would stream data from one of the sensors: the sampling rate of the sensors are different. I have not been able to find a starting code for this particular case, although I found some answers on SO suggesting to use select. Below is the code that I have so far. It's not working: after starting the 2 files, the code hangs there on both the subscriber and the publisher side, nothing is printed out.

publisher.py

import socket
import select

sock1 = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
sock2 = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
sock1.bind( ('', 23000) )
sock2.bind( ('', 23001) )

sock1.listen( 1 )
sock2.listen( 1 )
clisock1, (remhost, remport) = sock1.accept()
clisock2, (remhost, remport) = sock2.accept()
clisocks = [clisock1, clisock2]
while 1:

    ready_socks,_,_ = select.select(clisocks, [], [])
    for sock in ready_socks:

        sock.send(b"Hello World\n")

clisock1.close()
clisock2.close()

subscriber.py

import socket
import select

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

sock1.connect( ('', 23000) )
sock2.connect( ('', 23001) )

socks = [sock1, sock2]

while True:
    ready_socks,_,_ = select.select(socks, [], [])
    for sock in ready_socks:
        data, addr = sock.recvfrom(100) # This is will not block
        print("received message:", data)

I am at a loss, and I would very much appreciate some suggestions.

Upvotes: 0

Views: 267

Answers (1)

JohanL
JohanL

Reputation: 6891

The issue you are facing is due to you putting the transmit sockets in the wrong list. select.select() has two lists, a receive list and a transmit list. Thus, you need to update the line

    ready_socks,_,_ = select.select(socks, [], [])

in publisher.py to instead read

    _,ready_socks,_ = select.select([], socks, [])

where the transmit sockets are entered as the second argument and the sockets ready are in the second return value. If you update this, your program will work. However, it will send a large number of messages quickly, as you have no delays in your program. Also, as written, there is no way to distinguish between your two channels. I guess that is due to you reducing your example, though.

Upvotes: 1

Related Questions