2016-08-18 57 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脚本,则不需要它。 –