Python插座和Scapy嗅探UDP数据包

发布于 2025-02-07 14:50:00 字数 1371 浏览 2 评论 0原文

Windows10。Python3.7.8。 Scapy 2.4.5 我需要传输几个兆字节的数据。例如,我以这种方式使用套接字:

收发器:

import socket
UDP_IP = "192.168.13.172"
UDP_PORT = 0x1111
MESSAGE = b"... 1000 bytes data ..."
print("UDP target IP: %s" % UDP_IP)
print("UDP target port: %s" % UDP_PORT)
print("message: %s" % MESSAGE)

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
for x in range(0, 1500):
    sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))

接收器:

import socket
import select

UDP_IP = "192.168.13.172"
UDP_PORT = 0x1111
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # UDP
sock.bind((UDP_IP, UDP_PORT))

sock.setblocking(0)

total = b''
while True:
    reads, send, excepts = select.select([sock], [], [], 8)
    if reads:
        data, adr = sock.recvfrom(4000000)
        total += data
        print(len(total))
        if len(total) >= 1500000:
            break
    elif send:
        print(send)
    elif excepts:
        print(excepts)
    else:
        print('timeout')
        break

接收器输出:

162000
163000
164000
timeout

但是收发器发送了1500000字节。我在Wireshark日志中看到了它们。其他1500000-164000 = 1336000数据字节在哪里?

我也使用这样的Scapy:

data = sc.sniff(lfilter=lambda r: sc.UDP in r and sc.IP in r and r[sc.IP].src == ip_address, timeout=8)

Scapy还掉了一些数据包。我需要做什么才能获取所有发送的数据包?

Windows 10. Python 3.7.8. Scapy 2.4.5
I need to transfer several megabytes of data. For example, I use socket this way:

Transceiver:

import socket
UDP_IP = "192.168.13.172"
UDP_PORT = 0x1111
MESSAGE = b"... 1000 bytes data ..."
print("UDP target IP: %s" % UDP_IP)
print("UDP target port: %s" % UDP_PORT)
print("message: %s" % MESSAGE)

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
for x in range(0, 1500):
    sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))

And receiver:

import socket
import select

UDP_IP = "192.168.13.172"
UDP_PORT = 0x1111
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # UDP
sock.bind((UDP_IP, UDP_PORT))

sock.setblocking(0)

total = b''
while True:
    reads, send, excepts = select.select([sock], [], [], 8)
    if reads:
        data, adr = sock.recvfrom(4000000)
        total += data
        print(len(total))
        if len(total) >= 1500000:
            break
    elif send:
        print(send)
    elif excepts:
        print(excepts)
    else:
        print('timeout')
        break

Receiver output:

162000
163000
164000
timeout

But Transceiver sent 1500000 bytes. I saw them all in the Wireshark log. Where are other 1500000 - 164000 = 1336000 data bytes?

Also I used scapy like this:

data = sc.sniff(lfilter=lambda r: sc.UDP in r and sc.IP in r and r[sc.IP].src == ip_address, timeout=8)

And scapy also drops some packets. What I need to do to get all sent packets?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我三岁 2025-02-14 14:50:00

UDP是一个不可靠的协议。如果您发送太多数据太快,它可能会在实现和删除数据包中溢出缓冲区。如果您编号发送的数据包并将其与收到的数据包进行比较,则可以看到此信息。以下代码显示了这一点。

import socket
import select
import threading

UDP_IP = 'localhost'
UDP_PORT = 0x1111

def sender():
    with socket.socket(type=socket.SOCK_DGRAM) as sock:
        for x in range(1500):
            # message is 4-byte packet number repeated
            sock.sendto(x.to_bytes(4,'big') * 250, (UDP_IP, UDP_PORT))

def receiver():
    with socket.socket(type=socket.SOCK_DGRAM) as sock:
        sock.bind((UDP_IP, UDP_PORT))
        sock.setblocking(0)

        count = 0
        while True:
            reads, send, excepts = select.select([sock], [], [], 1)
            if reads:
                data, adr = sock.recvfrom(4096)
                number = int.from_bytes(data[:4],'big')
                print(count, number)
                if count != number:
                    break
                count += 1

            else:
                print('timeout',count)
                break

threading.Thread(target=receiver).start()
sender()

输出(使用打印可能会有所不同):

0 0
1 1
2 2
3 3
 .
 .
250 250
251 251
252 252
253 262           (dropped packets here)

有趣的是,请评论打印,并且仅在接收器中进行比较允许其跟上,至少在我的系统上。

输出(无打印)

timeout 1500

如果您需要可靠性,请使用TCP而非UDP。 UDP还可以接收到数据包,因此希望实现数据包编号,并在必要时请求删除数据包并重新订购。

UDP is an unreliable protocol. If you send too much data too fast, it can overflow buffers in the implementation and drop packets. You can see this if you number the packets sent and compare them to the number of packets received. The following code shows this.

import socket
import select
import threading

UDP_IP = 'localhost'
UDP_PORT = 0x1111

def sender():
    with socket.socket(type=socket.SOCK_DGRAM) as sock:
        for x in range(1500):
            # message is 4-byte packet number repeated
            sock.sendto(x.to_bytes(4,'big') * 250, (UDP_IP, UDP_PORT))

def receiver():
    with socket.socket(type=socket.SOCK_DGRAM) as sock:
        sock.bind((UDP_IP, UDP_PORT))
        sock.setblocking(0)

        count = 0
        while True:
            reads, send, excepts = select.select([sock], [], [], 1)
            if reads:
                data, adr = sock.recvfrom(4096)
                number = int.from_bytes(data[:4],'big')
                print(count, number)
                if count != number:
                    break
                count += 1

            else:
                print('timeout',count)
                break

threading.Thread(target=receiver).start()
sender()

Output (with print, may vary):

0 0
1 1
2 2
3 3
 .
 .
250 250
251 251
252 252
253 262           (dropped packets here)

Interestingly, commenting out the print and just doing the comparison in the receiver allows it to keep up, at least on my system.

Output (without print)

timeout 1500

If you want reliability, use TCP not UDP. UDP can also receive packets out-of-order, so expect to implement packet numbering and a way to request resend of dropped packets and re-order if necessary.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文