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 theelse:clause ofif data:. This is where you should put the code that reacts to a closed socket.