简体   繁体   中英

Python stateful socket programming

I have a client-server socket python script. I want to keep the state of each connection, such that I identify whether or not the client is its first connection. I unsuccessfully wrote the following code:

import socket,sys,SocketServer
from threading import Thread


class EchoRequestHandler(SocketServer.BaseRequestHandler):

    def setup(self):
        self.clients = {}
        print self.client_address, 'connected!'
        self.request.send('hi ' + str(self.client_address) + '\n')


    def setup(self):
        print self.client_address, 'connected!'
        self.request.send('hi ' + str(self.client_address) + '\n')

def getFile(self):
        fle = self.request.makefile('r')
        filename = fle.readline()
        print("Got filename {}\n".format(filename))
        data = 'fnord' # just something to be there for the first comparison
        with open(filename[:-1], 'w') as outfile:
            while data:
                #data = self.request.recv(1024)
                data = fle.read()
                #print('writing {!r} to file ....'.format(data))
                outfile.write(data)
                print("Finish {}\n".format(filename))
        print("finish handle")
def handle(self):
    addr = self.client_address[0] 
    print(self.clients)
    if addr not in self.clients:
        print("firsttime")
        self.clients[addr]=1
        print(self.clients)
    self.getFile()

def finish(self):
    print self.client_address, 'disconnected!'
    #self.request.send('bye ' + str(self.client_address) + '\n')

class ThreadedTCPServer(SocketServer.ThreadingMixIn, 
SocketServer.TCPServer):
    pass
if __name__=='__main__':
        #server = SocketServer.ThreadingTCPServer(('localhost', 50000), EchoRequestHandler)
        server = ThreadedTCPServer(('localhost', 60000), EchoRequestHandler)
        server.serve_forever()

Each time the client connect I am getting an empty clients dictionary. Seems like each time there is a connection setup is being called and empties the dictionary clients . How can I keep its state at each connection?

The threaded socket server creates a new instance of EchoRequestHandler for each connection, so storing the clients in that class instance would not be correct.

Each request handler instance has a self.server member that knows its server, so you can store it there instead.

Below is modified from a Python 2.7 SocketServer example in the module's help:

#!python2
import time
import socket
import threading
import SocketServer

class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):

    def handle(self):
        self.server.clients.add(self.client_address)
        print 'connected from',self.client_address
        print 'all clients =',self.server.clients
        data = self.request.recv(1024)
        cur_thread = threading.current_thread()
        response = "{}: {}".format(cur_thread.name, data)
        self.request.sendall(response)
        time.sleep(2)
        print 'disconnected'

class ThreadedTCPServer(SocketServer.ThreadingTCPServer):
    def __init__(self,*args,**kwargs):
        SocketServer.ThreadingTCPServer.__init__(self,*args,**kwargs)
        self.clients = set()

def client(ip, port, message):
    sock = socket.socket()
    sock.connect((ip, port))
    try:
        sock.sendall(message)
        response = sock.recv(1024)
        print "Received: {}".format(response)
    finally:
        sock.close()

if __name__ == "__main__":
    # Port 0 means to select an arbitrary unused port
    HOST, PORT = "localhost", 0

    server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)
    ip, port = server.server_address

    # Start a thread with the server -- that thread will then start one
    # more thread for each request
    server_thread = threading.Thread(target=server.serve_forever)
    # Exit the server thread when the main thread terminates
    server_thread.daemon = True
    server_thread.start()
    print "Server loop running in thread:", server_thread.name

    client(ip, port, "Hello World 1\n")
    client(ip, port, "Hello World 2\n")
    client(ip, port, "Hello World 3\n")

    server.shutdown()
    server.server_close()

Output:

Server loop running in thread: Thread-1
connected from ('127.0.0.1', 2360)
all clients = set([('127.0.0.1', 2360)])
Received: Thread-2: Hello World 1

connected from ('127.0.0.1', 2361)
all clients = set([('127.0.0.1', 2361), ('127.0.0.1', 2360)])
Received: Thread-3: Hello World 2

connected from ('127.0.0.1', 2362)
all clients = set([('127.0.0.1', 2361), ('127.0.0.1', 2362), ('127.0.0.1', 2360)])
Received: Thread-4: Hello World 3

disconnected
disconnected
disconnected

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM