2016-08-18 73 views
0

我有一個客戶端服務器套接字python腳本。我想保持每個連接的狀態,以便確定客戶端是否是其第一個連接。我失敗寫了下面的代碼:Python有狀態套接字編程

`

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

每一次客戶端連接我得到一個空的客戶字典。似乎每次有連接設置被調用並清空字典clients。我如何保持每個連接的狀態?

回答

1

線程套接字服務器爲每個連接創建一個新的EchoRequestHandler實例,因此將該類實例中的客戶端存儲將不正確。

每個請求處理程序實例都有一個知道其服務器的self.server成員,因此您可以將其存儲在那裏。

下面是一個Python 2.7 SocketServer的例子在模塊的幫助下修改:

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

輸出:

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

謝謝,這是我需要的。一個問題。在啓動服務器時,需要使用'server_thread = threading.Thread(target = server.serve_forever)'?在線程中啓動它。它不足以啓動它的方式:'server = ThreadedTCPServer(('localhost',60000),EchoRequestHandler)server.serve_forever()'? – curious

+1

@curious不,這只是客戶端和服務器都可以在一個Python進程中運行。如果您爲服務器和客戶端使用單獨的Python腳本,則不需要它。 –