如何计算TCPServer中的连接客户端数量?
我正在使用Python的SocketServer.ThreadingTCPServer。现在我想知道在某个时刻有多少个客户端连接着。
这个问题怎么解决呢?
2 个回答
0
在一个负责“服务”客户端的线程中,有一个全局计数器,当客户端连接时这个计数器会增加,断开连接时会减少。
如果你想从操作系统的层面来统计连接数,可以使用 nestat -an
命令,并配合合适的 grep
过滤器和 wc -l
命令(在Windows上需要使用 grep
和 wc
的移植版本)。
6
SocketServer.ThreadingTCPServer 会为每个连接的客户端创建一个新的线程,所以在某一时刻知道有多少个客户端连接,就等于知道有多少个线程在活动。你只需要使用 threading.activeCount,这样就能得到当前的客户端数量:
num_client = threading.activeCount() - 1 # Don't count the main thread.
当然,如果你的代码中还有其他地方也在创建线程,这样的方法就不一定准确了。为了修正这个问题,你可以重写 process_request() 和 process_request_thread() 这两个方法,增加一个客户端计数器。
根据这个例子 这里,我写了这段代码来测试这两种方法:
import time
import socket
import threading
from SocketServer import ThreadingTCPServer, BaseRequestHandler
def client(ip, port, message):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((ip, port))
sock.send(message)
response = sock.recv(1024)
sock.close()
class ThreadedTCPRequestHandler(BaseRequestHandler):
def handle(self):
data = self.request.recv(1024)
cur_thread = threading.currentThread()
response = "%s: %s" % (cur_thread.getName(), data)
self.request.send(response)
time.sleep(1)
class MyServer(ThreadingTCPServer):
def __init__(self, *args, **kws):
self._num_client = 0
ThreadingTCPServer.__init__(self, *args, **kws)
def process_request(self, *args, **kws):
print "swap thread"
self._num_client += 1
ThreadingTCPServer.process_request(self, *args, **kws)
def process_request_thread(self, *args, **kws):
ThreadingTCPServer.process_request_thread(self, *args, **kws)
print "kill thread"
self._num_client -= 1
def get_client_number(self):
return self._num_client
def my_client_count(ignore=1):
return threading.activeCount() - ignore
if __name__ == '__main__':
server = MyServer(("localhost", 0), ThreadedTCPRequestHandler)
server_thread = threading.Thread(target=server.serve_forever)
ip, port = server.server_address
server_thread.setDaemon(True)
server_thread.start()
print "client 1 connected"
client(ip, port, "Hello World 1")
print "number of client get_client_number : %s, enumerate : %s" \
% (server.get_client_number(), my_client_count())
print "client 2 connected"
client(ip, port, "Hello World 2")
print "number of client get_client_number : %s, enumerate : %s" \
% (server.get_client_number(), my_client_count())
time.sleep(3)
print "client 3 connected"
client(ip, port, "Hello World 3")
print "number of client get_client_number : %s, enumerate : %s" \
% (server.get_client_number(), my_client_count())
输出结果:
client 1 connected
swap client thread
number of client get_client_number : 1, enumerate : 2
client 2 connected
swap client thread
number of client get_client_number : 2, enumerate : 3
kill client thread
kill client thread
client 3 connected
swap client thread
number of client get_client_number : 1, enumerate : 2
正如你所看到的,第二种方法给出的值更准确。两种方法的区别在于,因为我的服务器是用线程运行的,所以总是多了一个线程,这就解释了结果差1的原因。
希望这能帮到你 :)