如何统计TCPServer中的连接客户端?

时间:2011-03-20 19:12:22

标签: python tcp network-programming

我正在使用Pythons SocketServer.ThreadingTCPServer。现在我想知道在某个时刻连接了多少客户端。

如何解决这个问题?

2 个答案:

答案 0 :(得分:5)

SocketServer.ThreadingTCPServer为每个客户端连接交换一个新线程,因此知道在某个时刻连接的客户端数量与知道当时有多少线程存活相同,所以只需使用threading.activeCount和数字客户将是:

num_client = threading.activeCount() - 1 # Don't count the main thread.

当然,如果您的代码的其他部分也交换线程,这将无法给您正确的结果,因此要修复您可以通过为客户端添加计数器来覆盖process_request()和process_request_thread()方法。 p>

从示例here我写了这段代码来测试两个方法

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线程解释了1的差异。

希望这可以帮助:)

答案 1 :(得分:0)

在“服务”客户端的线程中使用一些全局计数,该计数在客户端连接时增加,在断开连接时减少。

如果您想从操作系统级别进行计数,请使用nestat -an与正确的grep过滤器和wc -l(在Windows上使用grepwc的端口)