非阻塞TCP写入(2)已成功但请求未发送

时间:2009-02-25 08:07:45

标签: tcp nonblocking

我看到在源接口上看不到使用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;
    }
}     

3 个答案:

答案 0 :(得分:3)

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

如果返回-1,请检查errno。值EAGAIN表示write 发生,您必须再次执行此操作。

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

如果在短期套接字上发生这种情况,请阅读The ultimate SO_LINGER page, or: why is my tcp not reliable。它解释了关于变速器关闭部分的特殊问题。

  

当我们天真地使用TCP来发送我们需要传输的数据时,它通常无法做到我们想要的 - 最终的千字节或有时兆字节的数据从未到达。

结论是:

  

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

它还描述了Linux的黑客攻击。

答案 1 :(得分:1)

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

答案 2 :(得分:1)

您想要阅读TCP_NODELAY选项以及TCP发送缓冲区的性质。