You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 02:22:42