1

我看到在源接口上看不到使用 write(2) 写入非阻塞 TCP 套接字的一小组消息,也没有被目标接收。

可能是什么问题呢?应用程序有什么方法可以检测到这一点并重试?

while (len > 0) {
    res = write (c->sock_fd, tcp_buf, len);
    if (res < 0) {
      switch (errno) {
        case EAGAIN:
        case EINTR:
        <handle case>
        break;
        default:
        <close connection>
      }
    }
    else {
      len -= res;
    }
}     
4

3 回答 3

3

非阻塞write(2)意味着无论遇到什么困难,呼叫都会返回。检测发生了什么的正确方法是检查函数的返回值。

如果它返回 -1 检查errno。值EAGAIN意味着write没有发生,你必须再做一次。

它还可能返回一个短写入(即一个小于您传递给它的缓冲区大小的值),在这种情况下,您可能想要重试丢失的部分。

如果这种情况发生在短期套接字上,还请阅读The Ultimate SO_LINGER 页面,或者:为什么我的 tcp 不可靠。它解释了有关变速器关闭部分的特定问题。

当我们天真地使用 TCP 只发送我们需要传输的数据时,它通常无法完成我们想要的 - 最后的千字节或有时兆字节的传输数据永远不会到达。

结论是:

最好的建议是发送长度信息,并让远程程序主动确认已收到所有数据。

它还描述了针对 Linux 的 hack。

于 2009-02-25T08:30:31.940 回答
1

您想了解TCP_NODELAY选项和 TCP 发送缓冲区的性质。

于 2009-05-25T20:48:36.757 回答
1

write() 返回写入的字节数,这可能小于你发送的字节数,甚至为 0!确保检查并重新传输丢弃的任何内容(由于 NIC 上没有足够的缓冲区空间或其他原因)

于 2009-02-25T08:17:51.583 回答