Python 有状态套接字编程
Python stateful socket programming
我有一个客户端-服务器套接字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
。我怎样才能在每次连接时保持它的状态?
线程套接字服务器为每个连接创建一个新的 EchoRequestHandler
实例,因此将客户端存储在该 class 实例中是不正确的。
每个请求处理程序实例都有一个知道其服务器的 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
我有一个客户端-服务器套接字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
。我怎样才能在每次连接时保持它的状态?
线程套接字服务器为每个连接创建一个新的 EchoRequestHandler
实例,因此将客户端存储在该 class 实例中是不正确的。
每个请求处理程序实例都有一个知道其服务器的 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