2011-11-16 65 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。無論如何,現在我忙於其他工作,我會在一段時間內回覆。 –