如何用Python Socket获取完整的L2至L7网络数据?
捕获完整网络帧的Python服务器实现疑问
需求说明
我想要写一个简单的Python服务器,能接收任意来源的连接,解析包含以太网头部在内的完整网络帧,服务器收到帧后不需要维护连接或关注客户端状态(类似Wireshark的帧捕获能力,可视化部分不在本次需求内)。后续还需要支持捕获多帧序列,但不想自己处理TCP握手这类底层流程。
现有套接字方案的局限
- 传统
AF_INET/SOCK_STREAM套接字:只能获取数据载荷,拿不到网络层、链路层的头部信息,满足不了需求 AF_INET/SOCK_RAW套接字:可以获取L3(网络层)、L4(传输层)头部及数据,但无法捕获以太网头部(L2)AF_PACKET/SOCK_RAW套接字:理论上能获取从L2到L7的完整帧,但使用这种套接字时,网卡不会处理连接建立流程。当客户端正常发送TCP/UDP连接请求时,服务器不仅收不到数据,客户端还会报连接拒绝错误。
代码示例
客户端代码(client.py)
这个代码可以和普通回显服务器正常通信:
import socket HOST = '192.168.0.95' PORT = 5000 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.connect((HOST, PORT)) s.sendall(b'Hello, world')
测试服务器代码(server.py)
import socket PORT = 5000 ETH_P_ALL = 3 ETH_P_IP = 0x800 # 从其他答案复制的,不确定具体用途 s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(ETH_P_ALL)) s.bind(('wlp0s20f3', 5000)) # 绑定到指定网卡,因为原始套接字绑定的是接口而非IP地址 # 注:用回环接口(lo)经常会报管道破裂/连接拒绝,这个网卡目前没报错,但也收不到任何数据 while True: print(s.recvfrom(4096))
遇到的问题
- 上述服务器代码始终无法接收数据,客户端执行时会报错
ConnectionRefusedError: [Errno 111] Connection refused - 尝试改用
AF_PACKET/SOCK_RAW套接字作为客户端发送数据,Wireshark能抓到数据包,但服务器还是收不到
核心疑问
我是否应该继续使用AF_PACKET/SOCK_RAW套接字?或者有没有其他方法可以捕获完整的L2到L7请求?
内容的提问来源于stack exchange,提问作者CD1210
相关产品推荐
相关产品推荐

