I am implementing a server in Python. I have been following the tutorial on Doug Hellmann's blog:
I have a problem with select() not catching broken or closed pipe.
# Create socket
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Non blocking socket
serversocket.setblocking(0)
# Bind socket
serversocket.bind((HOST, PORT))
# Socket listening
serversocket.listen(5)
# Sockets from which we expect to read
inputs = [ serversocket ]
# Sockets to which we expect to write
outputs = [ ]
resign = re.compile("resign")
while inputs:
print "Waiting for connection..."
readable, writable, exceptional = select.select(inputs, outputs, inputs)
for s in exceptional:
print >>sys.stderr, 'handling exceptional condition for', s.getpeername()
# Stop listening for input on the connection
inputs.remove(s)
s.close()
for s in readable:
# SERVER LISTENS TO CONNEXION
if s is serversocket:
if some_stuff_is_true:
connection, client_address = s.accept();
print 'New connection from ', client_address
connection.setblocking(0)
inputs.append(connection)
# CLIENT READABLE
else:
data = s.recv(MAXLINE)
#If socket has data to be read
if data:
print data # Test if data correclty received
if resign.findall(data):
inputs.remove(s)
s.close()
When the client closes the socket normally, it is not catch by select, and when the client breaks the socket, it is not caught by `exceptional.
How to make this server robust to closed/broken sockets?
When a socket is cleanly closed by the remote end, then it will become "readable" for you. When you call recv(), you will get zero bytes back. Your code does not do anything in the else: clause of if data:. This is where you should put the code that reacts to a closed socket.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With