I want to receive data only if it is available. like Serial.available()
in Arduino. I want code like this:
if there is data:
receive and print
else:
print 'No data'
In fact, I do not want the program to stop just for receiving data.
You can call .setblocking(False)
on a socket to disable blocking mode. The call will raise a BlockingIOError
when it would otherwise block. But then you have to handle exceptions when you .accept()
or .recv()
on the socket and there is no connection ready or no data to receive.
For example:
try:
data = s.recv(1024)
print(data)
except BlockingIOError:
print('no data')
select.select
can be used to poll multiple sockets for data. Here's a quick example:
import socket
import select
server = socket.socket()
server.bind(('', 8000))
server.listen()
readables = [server] # list of readable sockets. server is readable if a client is waiting.
i = 0
while True:
# to_read will be a list of sockets with readable data
to_read, to_write, errors = select.select(readables, [], [], 0)
for sock in to_read: # iterate through readable sockets
if sock is server: # is it the server?
client, address = server.accept()
print(f'\r{address}: connected')
readables.append(client) # add the client
else:
# read from address client
data = sock.recv(1024)
if not data:
print(f'\r{sock.getpeername()}: disconnected')
readables.remove(sock)
sock.close()
else:
print(f'\r{sock.getpeername()}: {data}')
# a simple spinner to show activity
i += 1
print(r'/-\|'[i%4], end='\r', flush=True)
Example where two clients connected, sent something and disconnected:
('127.0.0.1', 2983): connected
('127.0.0.1', 2983): b'hello'
('127.0.0.1', 2985): connected
('127.0.0.1', 2985): b'there'
('127.0.0.1', 2983): disconnected
('127.0.0.1', 2985): disconnected
<spinner activity here>