2011-11-16 64 views
3

我写了简单的网络流量监视器以B/s和/或总数据传输(B中)获得传输速率。但是,当我通过使用ftp传输文件来测试它时(使用Total Commander),我无法将它作为文件大小来衡量总传输量。它总是比实际尺寸小得多。 我不知道如果我做错了什么.. 的BPF过滤我设置为python中的pcapy网络流量监视器

dst <IP of ftp server pc> 

下面是我的源代码:

import threading 
import sys 
import pcapy 
import time 
import logging as logger 

class NetMonitor(threading.Thread): 

    _timeout = 1 

    @classmethod 
    def get_net_interfaces(cls): 
     return pcapy.findalldevs() 

    def __init__(self, device, bpf_filter): 
     threading.Thread.__init__(self) 

     self.active = True 
     self._net_monitor = pcapy.open_live(device, 65535, 0, 1000) #self.timeout * 1000) 
     self._net_monitor.setfilter(bpf_filter) 
     #self.dumper = self.net_monitor.dump_open("pkt_dump.txt") 

     self._current_bytes_rate = 0 
     self.total_transfer = 0 # total number of Bytes transfered 

     #<--- this is to calc average transfer B/s 
     self._tmp_bytes_per_sec_sum = 0 # sums up B/s values from each dispatch iteration (eventually used to calc average value) 
     self._inc = 0 # number of dispatch iterations (eventually used to calc average B/s value) 
     #---> 

     self._dispatch_bytes_sum = 0 # sums up packets size for one dispatch call 


    def __handle_packet(self, header, data): 
     # method is called for each packet by dispatch call (pcapy) 
     self._dispatch_bytes_sum += len(data) #header.getlen() #len(data) 
     #logger.debug("h: ({}, {}, {}), d:{}".format(header.getlen(), header.getcaplen(), header.getts(), len(data))) 
     #self.dumper.dump(header, data) 


    def update(self): 
     self._dispatch_bytes_sum = 0 
     # process packets 
     packets_nr = self._net_monitor.dispatch(-1, self.__handle_packet) 
     self.total_transfer += self._dispatch_bytes_sum 

     self._inc += 1 
     self._current_bytes_rate = self._dispatch_bytes_sum # add single dispatch B/s -> timeout is 1 s 
     self._tmp_bytes_per_sec_sum += self._current_bytes_rate 

     logger.debug('inc:{}, current rate: {} B/s, avg rate: {} B/s, total:{} B'.format(self._inc, self.current_rate, self.avg_rate, self.total_transfer)) 

     return self._current_bytes_rate, packets_nr 



    def get_avg_bytes_rate(self): 
     if self._inc: 
      return self._tmp_bytes_per_sec_sum/self._inc 
     else: 
      return 0 

    def get_current_bytes_rate(self): 
     return self._current_bytes_rate 


    def run(self): 
     while(self.active): 
      self.update() 
      time.sleep(self._timeout) 


    # average B/s rate 
    avg_rate = property(get_avg_bytes_rate) 
    # current B/s rate 
    current_rate = property(get_current_bytes_rate) 





if __name__ == '__main__': 

    filter = ' '.join(sys.argv[2:]) 
    print filter 
    #nm0 = NetMonitor(pcapy.findalldevs()[0], filter) 
    nm1 = NetMonitor(pcapy.findalldevs()[1], filter) 

    nm1.start() 
    start_time = time.time() 
    while time.time() - start_time < int(sys.argv[1]): 
     print "current {} B/s, avg {} B/s, total transfer {} B".format(nm1.current_rate, nm1.avg_rate, nm1.total_transfer) 
     time.sleep(1) 

    nm1.active = False 
    nm1.join() 

    print "++++++ total: {}, avg: {}".format(nm1.total_transfer, nm1.avg_rate) 

任何意见是非常赞赏。 干杯。

回答

0

使用过滤器只捕捉有用的TCP数据流,FTP数据:

port ftp-data 

我建议还混杂模式拍摄,只有包头(你不需要完整的数据要知道长度):

open_live(device, 4096, True, 100) 

在你的处理程序中,使用header.getlen()是正确的。

+0

我检查了你的建议,注意到在open_live中改变snaplen值会改变接收到的数据包的长度。我的意思是读取数据包的大小越小越好。传输大约13 MB文件我可以通过更改snaplen值从1MB到甚至40 MB使用它 –

+0

我更正了我的答案,然后使用新过滤器重试。 – Massimo

+0

收到的数据大小仍然取决于我设置的snaplen。无论如何,现在我忙于其他工作,我会在一段时间内回复。 –