Background
I have a simple socket server setup that I am trying to allow simultaneous connections to and echo back the data. The client side launches several threads each making its own connection to the server. This works fine for the socket.send() call, but all subsequent calls cause either a “Connection reset by peer” or a “Broken pipe”. Note that I have not found the change that toggles the reset and broken pipe. I have looked here on SO for a solution, but I’m afraid I may not know what to search for.
Am I going about this in the wrong manner, or am I overlooking something in my setup?
Server
import SocketServer
class MyTCPHandler(SocketServer.BaseRequestHandler):
def handle(self):
self.data = self.request.recv(1024).strip()
print "{} wrote: {}\n".format(self.client_address[0], self.data)
self.request.send(self.data.upper())
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
server.serve_forever()
Client
import socket
import sys
import threading
import time
HOST, PORT = "localhost", 9999
def create_client():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
cur_thread = threading.current_thread()
sock.connect((HOST, PORT))
for x in range(55):
msg = "{}: {}\n".format(cur_thread.name, str(x))
# Connect to server and send data
print cur_thread.name + ": sending message\n"
sock.send(msg)
# Receive data from the server and shut down
received = sock.recv(2048)
print "RX:" + received
finally:
cur_thread = threading.current_thread()
response = "{}: Closing!\n".format(cur_thread.name)
print response
sock.close()
if __name__ == "__main__":
print "testing single thread"
#create_client()
print "starting threads"
client_1 = threading.Thread(target=create_client)
client_1.daemon = True
client_1.start()
client_2 = threading.Thread(target=create_client)
client_2.daemon = True
client_2.start()
time.sleep(20)
When you return from
handlethe socket is closed. Use a while loop and return fromhandleonly whenself.data == ''.recvreturns zero bytes when the client closes the connection. Also don’tstrip()the result until after testing the return value or you could get a false close. Finally, useThreadingTCPServeror the server can only handle one connection at a time.Example:
Also note the
send()is not guaranteed to send all bytes of message, so usesendall()or check the return value.recv()can also be tricky. TCP/IP is a streaming protocol and has no concept of message boundaries, so it is up to you to implement a protocol to check that you have received a complete message. It is possible to send 10000 bytes and receive less than that, requiring multiple receives to get the whole message. It is also possible to make two sends and receive both in one receive, or even all of one send and part of another. For your example simply buffering all receives until there is a\nin the message would do for a simple protocol.