我如何有2个进程监听20个端口,每个端口都有自己的asyncore.loop?

时间:2019-07-11 00:18:08

标签: python python-2.7 multiprocessing asyncore

我设法在主线程中拥有30个端口,而没有丢失任何软件包,但是如果我想听40个端口,我开始松散软件包。我可以通过topwatch /proc/net/udp看到这一点。 带有30个端口的CPU使用率达到100 pct,没有封装丢失,速率为1124.69 Mb / seg。但是,一旦我尝试侦听31个端口,便开始看到内核丢弃软件包。 当我尝试有2个进程时,它在第一部分运行良好,但是我无法完成对2个asyncore.loops的侦听并读取数据。

在我要测试的计算机上,我无法安装Python3或任何类似Twisted的库。因此,我必须使用python 2.7。

目前,我只是尝试计算每个端口的速率和总速率。

我认为我的问题是循环开始在每个进程上运行以及我处理进程对象的方式之后,我确定自己缺少一些东西。

import os
import logging
import asyncore
import socket
import multiprocessing
import time
import threading

BUFF_SIZE = 4096

logging.basicConfig(level=logging.DEBUG, format='(%(threadName)-10s) %(message)s',)

class PortReader(asyncore.dispatcher):
    def __init__(self, host, port):
        asyncore.dispatcher.__init__(self)
        self.host = host
        self.port = port
        self.create_socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.bind((host, port))
        self.cnt = 0
        self.t0 = 0
        self.tf = 0

    def readable(self):
        return True

    def writable(self):
        return False

    def handle_connect(self):
        logging.debug("%d -- Connected to: %s, %d" % (os.getpid(), self.host, self.port))
        self.t0 = time.time()

    def handle_read(self):
        data = self.recv(BUFF_SIZE)
        if data:
            self.cnt+=len(data)

    def handle_close(self):
        logging.debug("%d -- Desconnected from: %s, %d with %d" % (os.getpid(),self.host, self.port, self.cnt))
        self.close()
        self.tf = time.time() - self.t0

class Process(multiprocessing.Process):
    def __init__(self, cpu_number):
        super(Process, self).__init__()
        self.map = {}
    self.data_ports = range(8080 + (40/CPUS_TO_READ) * cpu_number, 8080 + (40/CPUS_TO_READ) * (cpu_number + 1))
    self.listeners =[]
    self.rate ={}

    def run(self):
        for port in self.data_ports:
            self.listeners.append(PortReader('192.168.0.1', port))

        self.map = asyncore.socket_map

        asyncore.loop(timeout=0.001, use_poll=False, map=self.map)

        #self.map = asyncore.socket_map
        #logging.debug(self.map)
        #self.thread= threading.Thread(target=asyncore.loop, kwargs= {'timeout':0.1, 'map':self.map}) # thread here also did not work
        #self.thread.start()

    def stop(self):
        logging.debug(asyncore.socket_map) # empty
        logging.debug(self.listeners) # empty...
        for listener in self.listeners:
            logging.debug(listener)
            listener.handle_close()
        #self.thread.join()

    def calculate_results(self):
        for listener in self.listeners:
            port = listener.port # I can read this Ok
            tf = listener.tf # I can read this Ok
            tbytes = listener.cnt # This one is empty
            self.rate[port] = tbytes/tf

 if __name__=='__main__':

    logging.debug(os.getpid())

    CPUS_TO_READ = 2

    adqtime = 60

    processes = [Process(cpu) for cpu in range(CPUS_TO_READ)]
    [p.start() for p in processes]

    time.sleep(adqtime)

    #print maps

    data = {}
    for process in processes:
        #logging.debug(process.map)
        process.stop() 
        process.calculate_results()
        data.update(process.rate)
        process.join()
    print data # empty
    for port in range(8080, 8080+40):
        print "{0:.2f} B/seg on port {1}".format(data[port], port)

0 个答案:

没有答案