0
votes

I have the following code, run with Python 2.7 (on Mac OS) (needed because it's going into a legacy application). If LISTEN_BACKLOG is less than the number of clients, then after a few iterations I will get a "Connection reset by peer" on one of the clients during the recv() call, and sometimes during the connect().

For example, if you run 1 instance of the server and 2 instances of the client, with LISTEN_BACKLOG = 1, then you will get the issue very quickly.

server.py

import socket

LISTEN_BACKLOG = 1

exit_condition = False
listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
listener.bind(('127.0.0.1', 12345))
listener.settimeout(0.2)
listener.listen(LISTEN_BACKLOG)

while not exit_condition:
    try:
        server = listener.accept()[0]
        server.send(' ')
        server.close()
    except socket.timeout:
        # Timed-out connection so go around and wait again
        pass

client.py

while True:
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.connect(('127.0.0.1', 12345))
    print "Connected"
    data = client.recv(1) # <-- Get "Connection reset by peer" here sometimes
    if data == ' ':
        print "Got Data"
    else:
        print "ERROR: Received data is wrong: ", data, "\n"
        break

    client.close()
    print "Closed"

I am using a small socket timeout for the socket accept on the server, because I need to periodically check an exit condition for the while loop in the larger application. I know this is not ideal, but regardless I would expect it to work.

Can you please help me understand why the "Connection reset by peer" occurs?

EDIT: I have also tried an updated version of my code with Python3 and the behaviour is the same: "Connection reset by peer" at the recv() line.

1
Increase the backlog, of course. Why wouldn't you? The usual settings are 5, 50, or 500. But yiou can't get 'connection reset' from connect(): you get 'connection refused'. 'Connection reset' from recv() is caused by a bug in the code, and not in the code you posted: possibly in the peer code. - user207421
In the real application there are many more clients, and I use a bigger backlog but the behaviour is still the same - I get “connection reset by peer” as soon as the number of clients is larger than the listen backlog. I would expect “connection refused” from the connect, but certainly not “connection reset by peer” from recv. - user1592096

1 Answers

0
votes

If anyone else is coming across the same issue, I believe it is only a problem on MacOS. Perhaps the python socket implementation has a bug in MacOS. I've tried on Linux and I cannot reproduce the issue there.