【发布时间】:2018-12-25 05:56:21
【问题描述】:
我正在尝试在路由器中读取数据包,例如在 python 中:
# (skipping the exception handling code here)
s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.ntohs(0x0003))
while True:
p = s.recvfrom(2000)
pkt = p[0]
# process pkt here ...
对相关问题 (36115971) 的回答说 UDP 与 TCP 数据的参数和方法不同(有人说 recv 用于 TCP,recvfrom 用于 UDP,而其他人则相反,同样有人说 1024 作为缓冲区TCP 的大小和 UDP 的更大,还有人说相反)。在我在路由器中读取的情况下,我没有用于 TCP 和 UDP 的不同套接字,所以我需要从同一个套接字读取两者,所以我对如何读取传入的数据包有点困惑。
(1) 如果我想同时读取 TCP 和 UDP 数据包,我应该使用 recv() 还是 recvfrom()?
(2) 调用是一次返回一个数据包,还是在缓冲区填满后返回?例如,如果我有一个 4096 字节的大缓冲区,并且传入的 2 个数据包每个有 2400 字节,那么调用会在第一个数据包结束后立即返回,还是在第二个数据包填满缓冲区后返回?
(2a) 同样的问题,但如果我有一个 2000 字节的较小缓冲区。很明显,在第一次调用时,我将获得第一个数据包的前 2000 个字节。但是在下一次调用时,我会得到第一个数据包的最后 400 个字节,还是第二个数据包的前 2000 个字节?
(3) 如果我在拨打下一个电话时被延迟,可能是因为我正忙于处理第一个数据集,我是否有丢失数据的危险,或者操作系统是否会保留其内部的传入数据包队列以提供给我下次打电话的时候?如果操作系统保留其内部队列,我在哪里可以找到有关其大小的信息?
注意:一些给定的答复存在分歧,所以让我对我的问题进行一些限制。希望这些限制将有助于给出更具体的答案。
(a) 我的目标是使用 python 套接字 嗅探传入的数据包。所以其他涉及 tcpdump 或 tshark 等的解决方案不在此范围内。
(b) 目标是仅嗅探传入的数据包。数据包重新排序(对于 TCP 等面向连接的协议)等其他细节不在范围之内,实际上它们是可以避免的开销。
【问题讨论】:
-
您可以按照您的描述进行操作,但我认为您必须定义两个绑定在同一个端口上的不同套接字,一个用于 TCP,一个用于 UDP。虽然如果您打算进行数据包级别检查,我会提出一个类似
scapy的框架,它允许您检查数据包是TCP 还是UDP。另请查看可能有用的this answer。另外,在Network Engineering 上问这个问题可能会更好。 -
感谢您的建议。我也在网络工程论坛上发布了这个问题 - networkengineering.stackexchange.com/questions/51862
-
@game0ver,我们不回答这样的网络工程问题
-
@MikePennington 好的,对不起,我不知道,我只是想,因为它与网络有很大关系,它可能更适合那里......
标签: python sockets networking tcp udp