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
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.
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)
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
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.
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)