我设法在主线程中拥有30个端口,而没有丢失任何软件包,但是如果我想听40个端口,我开始松散软件包。我可以通过top
和watch /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)