sockets - 在UDP套接字上即时更改SOL_SOCKET,SO_RCVBUF的可预期行为是什么?

标签 sockets networking linux-kernel udp setsockopt

如果我们在Linux系统上即时调整UDP服务器套接字的输入缓冲区的大小,将会发生什么?

setsockopt(sock, SOL_SOCKET, SO_RCVBUF, ...)
我对以下问题特别感兴趣:
  • 如果我缩小到缓冲区中当前的大小以下,是否会简单地删除最旧/最新的?数据报是否正确,或者是否可以刷新其中的所有内容,或更糟的是它会破坏数据,例如截断数据报?
  • 缩小缓冲区甚至会节省内存还是会阻止该内存被系统重用?
  • 行为是可预测的还是有时会随机出现?
  • 最佳答案

    首先,术语“缓冲区”可能令人困惑:内核实际上并未将包保存在固定大小的缓冲区中,而是保存在称为“积压”的队列中(请参阅 include/net/sock.h:400 )。通过SO_RCVBUFSO_SNDBUF设置的大小仅限制了积压的最大大小。

    If I shrink below what is currently in the buffer, would this simply drop the oldest/newest?


    不,保留已收到的内容。没有数据报被丢弃。当您执行setsockopt(SO_RECVBUF)时,唯一发生的就是the value of the sk_rcvbuf field of the socket is changed。不会执行其他任何操作。
    仅当接收到更多数据包时才能看到此操作的实际效果:接收到的所有后续数据报将被立即丢弃,并将继续丢弃,直到队列缩小到设置的大小以下(即用户空间接收到足够的数据报)为止。

    Would shrinking the buffer even save memory or something prevents that memory from being reused by the system?


    如前所述,由于“缓冲区”实际上不是缓冲区,并且没有固定大小,因此更改SO_RECVBUF不会立即更改任何内容。
    有两种情况:
  • 如果待办事项大小小于(或等于)指定的大小:新的最大大小将受到限制,因此它将在将来节省内存,但有可能丢失数据包。
  • 如果待办事项大小大于指定的大小:当用户空间接收到缓冲的数据包时,最终将释放内存,并且内存将不会再次超过设置的值。将来会再次节省内存。

  • Is the behavior predictable or could it behave randomly at times?


    看一下内核代码,我会说以我上面描述的方式是100%可预测的。但是,我不确定这在哪里记录。我想说的是,如果您考虑将“缓冲区”作为队列发送(实际上就是队列),那是一种直观的感觉。

    关于sockets - 在UDP套接字上即时更改SOL_SOCKET,SO_RCVBUF的可预期行为是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64523733/

    相关文章:

    Linux:数据包重新排序模拟

    Java套接字系统地址

    linux-kernel - Linux 内核模块 - 创建 proc 文件 - proc_root 未声明的错误

    c - Linux 模块拒绝对 BIOS 的写入权限?

    java - BufferedReader readLine 和 OutputStreamWriter .write

    python - 与服务器 Python 的多套接字连接

    networking - 谷歌或 Facebook 会面临遭受 DDoS 攻击的风险吗?

    assembly - 是否有 ARM 处理器支持片上硬件随机数生成器?

    通过套接字进行 Java 加密对象序列化

    sockets - 在 golang 中创建 TCP 客户端