捕获数据包理论上两种方法相同,结果不同

2024-06-07 17:19:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我有稳定的流源与恒定比特率=10.69Mbps。 我尝试用两种方法创建比特率分析器。一个是使用scapy sniff函数,另一个是使用sock.recv()的简单包长度计数器。你知道吗

最大的问题是,在第一种情况下,程序每3-5秒就会“阻塞”:(10.516,10.527,10.527,9.926,10.526[Mbps])

在第二种情况下,结果远低于真实值:(10.251,10.201,10.201,10.221,10.201[Mbps])

我的结论是,使用scapy的方法比另一种方法要多捕获大约40-50个数据报。你知道吗

import socket
import struct
import timeit
from collections import Counter
from scapy.all import sniff
#___________________________part not affecting code_______________________
MCAST_GRP = '239.0.1.104'
MCAST_PORT = 12345
IS_ALL_GROUPS = True

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if IS_ALL_GROUPS:
    sock.bind(('', MCAST_PORT))
else:
    sock.bind((MCAST_GRP, MCAST_PORT))
mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)


#__________________________Actual problems___________________________
packet_counts = Counter()
capturedPacketsSize = 0

## Defining custom function that sums sizes of captured packets
def custom_action(packet):
    global capturedPacketsSize
    capturedPacketsSize += len(packet)    
    #key = tuple(sorted([packet[0][1].src, packet[0][1].dst]))
    #packet_counts.update([key])

#Scapy approach
print("_____.:|   Starting analyse of bitrate!   |:._____")
for x in range(10):
    pkt = sniff(iface="eno4", filter="ip host 239.0.1.104", prn=custom_action, timeout=1)
    MCbitrate = round((capturedPacketsSize*8)/(1024*1024),3)
    print(MCbitrate)
    capturedPacketsSize = 0

#General approach
totalSize = 0
print("_____.:|   Starting analyse of bitrate!   |:._____")
while 1:
    stop = time.time() + 1
    while (time.time()<stop):
        #datagram = sock.recv(bufferUDP)
        totalSize += len(sock.recv(bufferUDP))


    theoreticalBitrate = (8*totalSize)/(1024*1024)
    print(round(theoreticalBitrate,3))
    totalSize = 0

所以你可以看到,两者的想法是一样的。但结果并非如此。 你有什么办法来提高without scapy approach的准确度或消除scapy approach的“阻塞”吗?你知道吗


解决方案

我相信我的结论可能是错的。在@Shir提示之后,我检查了每个解决方案(不考虑scapy阻塞)中每秒有大约1016+/-2个数据包。你知道吗

print(len(sock.recv()))的结果给出1316,这是(我假设)解封数据报的大小。1016*1316*8=10.696.448位。你知道吗

通过这个简单的数学,我意识到,我的分母Mega,应该是(1000*1000)表示Bits,而它是(1024*1024),这对于Bytes是正确的。你知道吗


Tags: 方法importtimepacketsocketscapysockprint

热门问题