【问题标题】:Can a minimum number of bytes be set for python's socket.recvfrom()?可以为 python 的 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() 返回之前指定最小字节数?感谢您的帮助!

【问题讨论】:

    标签: python python-3.x sockets udp packet


    【解决方案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 个字的数据报将起作用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-16
      • 2011-03-25
      • 2017-01-31
      • 2019-02-16
      • 1970-01-01
      • 2011-04-14
      相关资源
      最近更新 更多