可以为 python 的 socket.recvfrom() 设置最小字节数吗?

Posted

技术标签:

【中文标题】可以为 python 的 socket.recvfrom() 设置最小字节数吗?【英文标题】:Can a minimum number of bytes be set for python's socket.recvfrom()? 【发布时间】:2022-01-10 04:59:28 【问题描述】:

我从我的服务器发送了两种类型的数据包并尝试分析:

上下文数据包,长度为 27 个字(108 字节)

数据包,长度为 250 个字(1000 字节)

我正在使用 python 的 socket recvfrom() 方法,但有关此的文档似乎很少。目前我有以下代码 sn-p:

import socket


rx_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
rx_socket.bind(("", 50000))

packets = []
for _ in range(10):
    data, _ = rx_socket.recvfrom(8192)
    packets.append(data)

我的问题是每个以packets 列表结尾的数据包都是一个上下文数据包。我知道这一点是因为每个元素的长度是 27。我需要能够接收数据包,有没有办法在 recvfrom() 返回之前指定最小字节数?感谢您的帮助!

【问题讨论】:

【参考方案1】:

我的问题是每个以packets 列表结尾的数据包都是一个上下文数据包。我知道这是因为每个元素的长度是 27。

好吧,您只读取了 10 个数据包,然后就停止了。 data 数据包是否可能在第 10 个数据包之后到达?

我需要能够接收data 数据包

您已经拥有的recvfrom() 呼叫将非常适合此目的。您正在告诉recvfrom() 使用 8K 缓冲区读取 next 数据报。您的 data 数据包在该大小范围内。

如果有的话,您唯一需要更改的是循环条件,例如使用while True 而不是for _ in range(10)

如果您没有收到任何data 数据包,这意味着您要么在它们到达之前停止读取,要么它们根本没有被发送到您的侦听端口。使用数据包嗅探器(如 Wireshark)来验证这一点。

有没有办法在 recvfrom() 返回之前指定最小字节数?

不,没有。对recvfrom() 的每次调用都将出列并返回套接字上的下一个数据报,无论其大小如何。但是,如果数据报大于您指定的缓冲区大小,则数据报将被截断。

【讨论】:

【参考方案2】:

有没有办法在 recvfrom() 返回之前指定最小字节数?

没有。只能指定要读取的最大字节数。

请注意,虽然对于数据报(即 UDP),每个recv 将只返回一个数据报,而send 将在一个数据报中发送给定的所有内容,这也意味着send 之间存在 1:1 的关系一边和recv 在另一边。

此外,不可能根据那里的大小选择数据报并让系统忽略其他数据报。一切都按收到的顺序传送到套接字缓冲区(只要有空间)。获取更大数据报的唯一方法是通过调用 recv 显式删除之前收到的每个数据报。

【讨论】:

这是否意味着无论缓冲区有多大,每次调用recv() 都会返回一个数据包?也许添加 while True 并检查直到长度超过 27 会有所帮助? @Tonysres:是的,每次调用recv 都会返回下一个数据报。如果给定长度小于数据报长度,那么其余数据将被丢弃,即不会在下一个recv 中返回。因此,使用recv 循环并跳过所有包含 27 个字的数据报将起作用。

以上是关于可以为 python 的 socket.recvfrom() 设置最小字节数吗?的主要内容,如果未能解决你的问题,请参考以下文章

向量之间的角度 - 只有长度为1的数组可以转换为Python标量

python中字符类型是不是可以强制转化为bool类型

python 使用eval() 可以将json格式的数据,转换为原始数据

python回归预测数据怎么导出?

为没有python的用户创建一个python exe - 可以处理服务器CGI

可以为 python 的 socket.recvfrom() 设置最小字节数吗?