2

I am testing a Python web server. It works as expected using localhost as the server and client, but when I test on different computers, I am getting

[Errno 54] Connection reset by peer about 20% - 80% of the time, depending on how many client threads I spawn at once. Why?

Code Snippets
Server listens:

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((self.interface, self.port))
sock.listen(5)

Server loops forever, accepts client connection, spawns new thread:

while True:
    (clientsock, (ip, port)) = self.sock.accept()
    newthread = ClientThread(ip, port, clientsock)              
    newthread.start()

Spawn a bunch of client threads which connect with server, send message which requests a file, and then closes connection

Server sends message to client when ready

self.socket.sendall(message.encode())

After message is sent, close the write end of connection:

self.socket.shutdown(socket.SHUT_WR)

Client receives message (error occurs here)

def receive(self):
    data_string = ''
    bytes = self.sock.recv(self.bufsize)
    while len(bytes) > 0:
        bytes_str = bytes.decode('UTF-8')
        data_string += bytes_str
        bytes = self.sock.recv(self.bufsize)
    return data_string

After client thread has received message, close the connection:

self.socket.close()
cosmosa
  • 743
  • 1
  • 10
  • 23
  • You should share your code (at least a simplified one). Otherwise is impossible to answer, – Michele d'Amico May 01 '15 at 19:48
  • @Micheled'Amico, updated with code. Please let me know if that helps or you need more. – cosmosa May 01 '15 at 19:55
  • 1
    `sock.listen(5)` allows a backlog of 5 pending connect requests so you'll get this kind of behavior if accepts are a bit slow - common w/ network latency added into the mix. Up that number and throttle back that client a bit when you get the conn refused feedback. – tdelaney May 01 '15 at 21:18
  • I'm not sure but maybe that is the correct behavior http://stackoverflow.com/questions/1434451/what-does-connection-reset-by-peer-mean . When you shutdown your socket you send a reset pck. On localhost is little bit different because use loopback. You should handle this kind of exception as normal socket closing events. I guess that you don't lost any data even you have these exceptions. – Michele d'Amico May 01 '15 at 21:28

1 Answers1

0

Receive function had errors. Changed to this:

def receive(self):
    data_string = ''
    while True:
        bytes = self.sock.recv(self.bufsize)
        bytes_str = bytes.decode('UTF-8')
        data_string += bytes_str
        if not bytes:                   
            break
    return data_string

Old receive function would try to call recv a second time when server had already closed socket. New one only calls once.

Also did not know you could increase listening socket backlog > 5 since Python docs say generally 5 is max, when on OS X it is 128. Increasing backlog to 128 helped.

cosmosa
  • 743
  • 1
  • 10
  • 23