【问题标题】:What is the maximum len to recv/recvfromrecv/recvfrom 的最大 len 是多少
【发布时间】:2020-10-07 12:16:13
【问题描述】:

当我用

监听 TCP 或 UDP 套接字时

ssize_t recv(int sockfd, void *buf, size_t len, int flags);

或者

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flag , struct sockaddr *src_addr, socklen_t *addrlen);

有一个参数叫len

在 linux 中,我可以使用这些函数读取的最大缓冲区 len 是多少?是 65336 吗?那定义在哪里?

如果套接字中的字节数比这个数字多,会发生什么?他们会辍学吗?或者我会在下一个循环中阅读它们?

【问题讨论】:

  • 什么样的socket? UNIX、UDP、TCP?
  • 当然len仅限于SIZE_MAX,所以最大值不会高于这个。
  • SIZE_MAX 在 32 位系统中是 65336?那是我可以从套接字读取的最大缓冲区 len 吗?如果超过此限制的数据会发生什么?

标签: c linux sockets buffer recvfrom


【解决方案1】:

由于len 属于size_t 类型,其最大大小由SIZE_MAX 定义。 C 标准规定 SIZE_MAX 必须至少为 65535。 但是,没有上限,所以它的实际值取决于编译器。

size_tSIZE_MAX<stdint.h> 中定义。

如果字节数超过指定的len 会发生什么情况取决于您拥有的套接字类型。

如果你有一个 TCP 套接字(SOCK_STREAM 类型),如果等待读取的字节数多于 len 的值,那么下次调用 recv() 时会读取它们。

但是,如果您的套接字类型为 SOCK_DGRAM(一个 UDP 套接字),则对 recvfrom() 的调用将始终读取整个数据报。如果数据报的长度大于len,则第一个len 字节将被读入您的缓冲区,其余字节将丢失。

在这种情况下,recvfrom() 返回 -1 并将 errno 设置为 EMSGSIZE,这就是您测试是否发生这种情况的方法。

【讨论】:

    【解决方案2】:

    理论上,您可以读取任意大小的缓冲区。 size_t 的最大值由 C 标准保证至少为 65535,但是在现代 Linux 系统上它至少为 232-1,如果不是 264支持>-1.

    对于 TCP,由于它是一个流式协议,任何未读取的字节都将保留在缓冲区中,等待下一次迭代读取。

    对于 UDP,一次只能读取一个完整的数据报,如果缓冲区不足以容纳数据报,则任何多余的字节都会丢失。此外,由于 UDP 协议没有内置可靠性,如果读取速度不够快,数据报可能会丢失。

    【讨论】:

      猜你喜欢
      • 2017-12-23
      • 2013-02-26
      • 2012-06-30
      • 2011-03-13
      • 1970-01-01
      • 2015-05-21
      • 2011-06-15
      • 2021-12-25
      • 2011-05-05
      相关资源
      最近更新 更多