我看到在源接口上看不到使用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;
}
}
答案 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发送缓冲区的性质。