Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - select() does not catch broken socket

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?

like image 214
Béatrice Moissinac Avatar asked Dec 01 '25 18:12

Béatrice Moissinac


1 Answers

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.

like image 173
Greg Hewgill Avatar answered Dec 03 '25 08:12

Greg Hewgill



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!