我有一个问题 - 当我试图通过posix套接字发送大量数据时(无论文件或某些数据无关紧要)在某些时候我没有得到我所期望的 - 我使用wireshark来确定导致错误的是什么,我发现,正是在我的应用程序中断时,有两个方向发送的标记为红色的数据包说“零窗口”或“窗口已满”。
结果是,应用层没有得到send()函数发送的数据。它虽然得到了下一部分......
我做错了吗?
编辑:
让我们说我想发送19232个数据,每个1024字节 - 在某个随机点(或根本不发送)而不是第9344个数据包我得到第9345个。我没有实现任何重传协议,因为我认为TCP是为我做的。
答案 0 :(得分:1)
Zero Window / Window Full表示TCP连接的一端无法接收更多数据,直到其客户端应用程序读取已收到的某些数据为止。换句话说,它是连接的一面告诉另一方“除非我告诉你,否则不再发送任何数据”。
TCP 处理重新传输。你的问题很可能是:
send()
返回0
(没有写入字节),或-1
errno
设置为EWOULDBLOCK
send()
已发送您要求发送的所有数据。这会导致数据丢失。您需要修复发送方以使其处理send()
失败,包括返回小于您要求它发送的字节数的值。如果套接字是非阻塞的,这意味着等到select()
告诉您套接字可写之后再重试。
答案 1 :(得分:1)
首先,TCP是字节流协议,而不是基于数据包的协议。仅仅因为您发送了一个1024字节的块并不意味着它将以这种方式接收。如果你正在快速填充管道以获得零窗口条件(即,接收缓冲区或发送缓冲区中没有更多空间)那么接收器代码很可能在某一时刻能够读取远比你的“数据包”的大小更多。
如果您没有特别请求非阻塞套接字,那么send
和recv
都将以零窗口/窗口满状态阻塞,而不是返回错误。
如果你想粘贴接收器端的代码,我们可以看看,但从你所描述的内容来看,你的第9344次读取实际上可能会获得比数据包大小更多的字节。您是否检查了从recv
返回的值?
答案 2 :(得分:0)
您的网络iperf是否也无法发送此数量的此类数据包?如果没有,请检查他们如何发送这些数据。
答案 3 :(得分:0)
嗯,从我在Wikipedia上看到的,这可能是某种缓冲区溢出(接收器报告零接收窗口)。只是一个猜测。