2016-08-18 2 views
0

Ich habe ein Client-Server-Socket-Python-Skript. Ich möchte den Zustand jeder Verbindung beibehalten, so dass ich feststellen kann, ob der Client seine erste Verbindung ist oder nicht. Ich schrieb erfolglos den folgenden Code:Python Statefull-Socket-Programmierung

`

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

Jedes Mal, wenn der Client eine Verbindung erhalte ich ein leeres Kunden Dictionary. Scheint wie jedes Mal, wenn eine Verbindung ist Setup wird aufgerufen und leert das Wörterbuch clients. Wie kann ich seinen Zustand bei jeder Verbindung halten?

Antwort

1

Der Threaded-Socket-Server erstellt für jede Verbindung eine neue Instanz von EchoRequestHandler, sodass das Speichern der Clients in dieser Klasseninstanz nicht korrekt ist.

Jede Request-Handler-Instanz hat einen self.server Member, der seinen Server kennt, so dass Sie ihn stattdessen dort speichern können.

Im Folgenden wird aus einem in der Hilfe des Moduls 2.7 Socket Beispiel Python geändert:

#!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() 

Ausgang:

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 
+0

Danke, das ist das, was ich brauche. Eine Frage. Wenn Sie den Server starten, müssen Sie ihn in einem Thread mit 'server_thread = threading.Thread (target = server.serve_forever) 'starten. Es reicht nicht aus, wie ich es starte: 'server = ThreadedTCPServer (('localhost', 60000), EchoRequestHandler) server.serve_forever()'? – curious

+1

@curious Nein, das war nur so, dass die Clients und der Server alle in einem Python-Prozess laufen konnten. Wenn Sie separate Python-Skripts für den Server und den Client haben, ist dies nicht erforderlich. –