Scapy发送的UDP数据包无法被Python原生脚本接收求助
Scapy发送的UDP包无法被Python原生Socket接收的解决方法
问题背景
用Scapy构造并发送的UDP包可被Wireshark捕获,但绑定127.0.0.1:25516的Python原生UDP客户端无法接收;而Python原生Socket发送的包能正常被接收,且因业务需求必须使用Scapy处理pcap文件。
核心原因
- Scapy的
send()函数默认直接在链路层发送数据包,绕过了操作系统内核的UDP协议栈;而Python原生UDP客户端的socket是监听内核UDP栈的数据包,因此无法捕获到Scapy直接发送的包。 - 代码中指定了物理网卡
enp5s0,但127.0.0.1的回环流量应走本地回环接口(Linux为lo,Windows为Loopback Pseudo-Interface 1),物理网卡不会处理回环数据包。
解决方法
方法1:用Python原生Socket发送Scapy构造的数据包
这种方法既保留Scapy构造复杂数据包的能力,又能让数据包进入内核UDP栈,确保被接收端捕获。代码如下:
from scapy.layers.inet import IP, UDP import socket UDP_IP = "127.0.0.1" UDP_PORT = 25516 # 用Scapy构造UDP数据包 packet = IP(dst=UDP_IP) / UDP(sport=25515, dport=UDP_PORT) / "Test123" # 提取IP层及以上的原始字节(跳过链路层) raw_packet = bytes(packet[IP]) # 使用RAW Socket发送数据包(需要root/管理员权限) with socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_UDP) as s: s.sendto(raw_packet, (UDP_IP, UDP_PORT)) print("Scapy构造的UDP包已发送")
方法2:调整Scapy发送参数,指定回环接口
修改Scapy发送代码,指定回环接口,让回环流量走正确的路径:
from scapy.layers.inet import * from scapy.sendrecv import send # Linux下回环接口为"lo",Windows下替换为对应回环接口名称 send(IP(dst="127.0.0.1") / UDP(sport=25515, dport=25516) / "Test123", iface="lo")
注意:部分系统下Scapy的
send()仍可能绕过内核栈,此时方法1的可靠性更高。
验证步骤
- 先启动Python原生UDP客户端
- 运行修改后的Scapy发送代码
- 客户端应正常输出:
Received message from ('127.0.0.1', 25515): b'Test123'
内容的提问来源于stack exchange,提问作者StragaSevera
相关产品推荐
相关产品推荐

