Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TCP server is closing connections

Tags:

python

I have this code

class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):

    def handle(self):
        _data = self.request.recv(1024)

        Utils.log("Received from %s: %s" % (self.client_address, _data))

calling it with

kamcon_server = ThreadedTCPServer((HOST, 3011), ThreadedTCPRequestHandler)

server_thread = threading.Thread(target = kamcon_server.serve_forever)
server_thread.setDaemon(True)
server_thread.start()

I can connect to the host, and the server can send the data, but when the client sends something to the server, the connection is automatically closed. Why? Thank you.

like image 247
Mejmo Avatar asked Apr 26 '11 16:04

Mejmo


2 Answers

Your handle() method is only calling recv() once per connection. If you want to handle multiple messages from the client, you need to loop. You should think about your protocol as well, so that you can handle request/response messages larger than 1024 bytes (e.g. parse _data and figure out if you have a complete message, buffer partial requests, etc).

For example:

def handle(self):
    close = 0
    while not close:
        _data = self.request.recv(1024)
        if not _data:
            # EOF, client closed, just return
            return
        Utils.log("Received from %s: %s" % (self.client_address, _data))
        self.request.send('got %d bytes\r\n' % len(_data))
        if 'quit' in _data:
            close = 1

Client session:

% telnet localhost 3011
hi
got 4 bytes
bye
got 5 bytes
telnet> quit
like image 192
samplebias Avatar answered Sep 22 '22 11:09

samplebias


Try this code, it allows multiple connections to same port and not close socket until client do it:

import SocketServer
import socket, threading

class MyTCPHandler(SocketServer.BaseRequestHandler):
        BUFFER_SIZE = 4096
        def handle(self):
                while 1:
                        #get input with wait if no data
                        data = self.request.recv(self.BUFFER_SIZE)
                        #suspect many more data (try to get all - without stop if no data)
                        if (len(data)==self.BUFFER_SIZE):
                                while 1:
                                        try: #error means no more data
                                                data += self.request.recv(self.BUFFER_SIZE, socket.MSG_DONTWAIT)
                                        except:
                                                break
                        #no data found exit loop (posible closed socket)
                        if (data == ""): break

                        #processing input
                        print "%s (%s) wrote: %s" % (self.client_address[0], threading.currentThread().getName(), data.strip())

if __name__ == "__main__":
        HOST, PORT = "localhost", 9999
        server = SocketServer.ThreadingTCPServer((HOST, PORT), MyTCPHandler)
        server.serve_forever()

You can also use ForkingTCPServer instead ThreadingTCPServer.

like image 39
vnaz Avatar answered Sep 23 '22 11:09

vnaz