Why does this socket connection allow only 1 send and receive?

Background
I have a simple socket server setup with which I am trying to allow simultaneous connection and repeat data. The client side launches several threads, each of which makes its own connection to the server. This works fine for calling socket.send (), but all subsequent calls cause either “Connection reset by peer” or “Broken pipe”. Please note that I did not find changes that switch reset and broken channel. I looked at SO here for a solution, but I'm afraid I don't know what to look for.

Am I wrong about this, or am I not noticing 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() 

Customer

 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) 
+4
source share
1 answer

When you return from handle , the socket will be closed. Use a while loop and return from handle only with self.data == '' . recv returns null bytes when the client closes the connection. Also do not do strip() results until you check the return value or get a false close. Finally, use ThreadingTCPServer , or the server can only handle one connection at a time.

Example:

 import SocketServer class MyTCPHandler(SocketServer.BaseRequestHandler): def handle(self): while True: self.data = self.request.recv(1024) if self.data == '': break self.data = self.data.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.ThreadingTCPServer((HOST, PORT), MyTCPHandler) server.serve_forever() 

Also note that send() does not guarantee the sending of all bytes of the message, so use sendall() or check the return value. recv() can also be complicated. TCP / IP is a streaming protocol and has no concept of message boundaries, so you need to implement the protocol to verify that you have received the full message. You can send 10,000 bytes and receive less than what is required, requiring multiple reception to receive the entire message. It is also possible to make two parcels and receive both in one receiver, and even in one shipment and part of another. For your example, just buffering all will be received until there is \n in the message for a simple protocol.

+8
source

Source: https://habr.com/ru/post/1386848/


All Articles