OSError: [Errno 57] Socket is not connected (socket programming in python macos)

Question:

I have a p2p network that peers ask tracker (server) for each other port number (with udp) and make a TCP connection to each other (p2p) with tcp on the same port that they have made UDP connection with server (tracker). These are done properly.

Client server (udp to tracker) works fine but when one peer wants to connect to another peer with tcp connection fails and I don’t know why it happens.

Client Peer Code:

tcp_socket = socket(AF_INET, SOCK_STREAM)
tcp_socket.connect(('127.0.0.1', seeder)) # seeder is server peer port number
tcp_socket.send('a.txt'.encode())
file_content = tcp_socket.recv(1024).decode()
print(file_content)

Server Peer Code:

tcp_socket = socket(AF_INET, SOCK_STREAM)
tcp_socket.bind(('127.0.0.1', port))
tcp_socket.listen(3)
while True:
    connection, _ = tcp_socket.accept()
    filename = tcp_socket.recv(1024).decode() #error at this line
    print('request: ', filename)

(a peer has udp and tcp connection on the same port. server peer’s tcp handler is running in separate thread from its udp handler)

Error in client peer:

ConnectionResetError: [Errno 54] Connection reset by peer

Error in server peer:

OSError: [Errno 57] Socket is not connected
Asked By: Mahdi

||

Answers:

You are attempting a recv on the listening socket tcp_socket, not the accepted socket connection. The server errors and exits causing the error on the client. Instead, do

tcp_socket = socket(AF_INET, SOCK_STREAM)
tcp_socket.bind(('127.0.0.1', port))
tcp_socket.listen(3)
while True:
    connection, _ = tcp_socket.accept()
    filename = connection.recv(1024).decode() #error at this line
    print('request: ', filename)

There is another problem. TCP does not guarantee that you recv on the same byte boundaries that you send. You need a way for the server to know that it has a fully received message before it can start to decode. Otherwise you risk a partial-character decode error.

You should also decide on a string encoding method otherwise you risk the default on different machines being different.

One option is to always use UTF-8 and to use a newline to known when a message can be decoded.

Answered By: tdelaney

This is happening because you are trying to use the recv method on the listening socket instead on the accepted (connected) socket. You should replace the tcp_socket.recv with connection.recv:

tcp_socket = socket(AF_INET, SOCK_STREAM)
tcp_socket.bind(('127.0.0.1', port))
tcp_socket.listen(3)
while True:
    connection, _ = tcp_socket.accept()
    filename = connection.recv(1024).decode()
    print('request: ', filename)
Answered By: nokla
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.