【问题标题】:What happens on buffer overflow?缓冲区溢出会发生什么?
【发布时间】:2012-09-04 18:35:48
【问题描述】:

我在某处读到每个 TCP 连接都有自己的 125kB 输出和输入缓冲区。如果这个缓冲区已满,我仍然继续在 linux 上发送数据会怎样?

根据http://www.kernel.org/doc/man-pages/online/pages/man2/send.2.html,数据包只是默默地丢弃,没有通知我。我能做些什么来阻止这种情况发生?有什么方法可以查明我的至少部分数据是否已正确发送,以便稍后继续?

【问题讨论】:

  • 请记住,send() 和各种风格可用于任何类型的套接字、TCP 或 UDP。当写入缓冲区已满时,流套接字应该阻塞,而 UDP 套接字可以(并且将)丢弃它。
  • 但我不想让它阻塞,我只想在有空间可用时重试:)
  • 阻塞是否意味着我必须等待其他设备下载数据并发送答案:“好的,我收到了数据包。”还是阻塞只是阻塞直到 linux 发送它们?
  • 如果你只是想“如果有可用空间重试”,那么将你的套接字置于非阻塞模式并使用 poll、select 或 epoll。
  • 另外,TCP 套接字中没有“数据包”之类的东西。 (在较低的 TCP 层,但它不暴露给应用程序)。 TCP 套接字是基于流的。当您调用“发送”时,它不会将数据作为数据包发送。它通过几个数据包发送它。接收数据的应用可能不会一次获取所有数据。

标签: c++ linux sockets tcp buffer


【解决方案1】:

简短的回答是这样的。 TCP 套接字上的“发送”调用只会阻塞,直到 TCP 滑动窗口(或内部队列缓冲区)由于远程端点接收和使用数据而打开。这与尝试将字节写入文件的速度快于磁盘可以保存文件的速度没有太大区别。

如果您的套接字配置为非阻塞模式,则 send 将返回 EWOULDBLOCK 或 EAGAIN,直到可以发送数据。标准的 pollselectepoll 调用将按预期工作,因此您知道何时再次“发送”。

【讨论】:

  • 如果操作系统缓冲区中的可用空间太小而无法处理给定的缓冲区,我会得到 EWOULDBLOCK 或 EAGAIN?
  • @ThomasSchmidt - 正确,假设您的套接字设置为非阻塞。 kegel.com/dkftpbench/nonblocking.html
  • 很好的答案,只是您将拥塞窗口与滑动窗口混淆了。将“拥塞”更改为“滑动”,您就可以了。参见例如Wikipedia
【解决方案2】:

我不知道“数据包被丢弃”。我认为更有可能的是程序对 write() 的调用将阻塞或返回失败。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多