C++ 通过posix套接字发送文件时的零窗口
我有一个问题——当我试图通过posix套接字发送大量数据(不管是文件还是一些数据)时,在某个时刻我没有收到我所期望的数据——我使用wireshark来确定是什么导致了错误,我发现,就在我的应用程序崩溃的时候,有标记为红色的数据包说“零窗口”或“零窗口”“窗口已满”向两个方向发送 结果是,应用程序层没有得到send()函数发送的一段数据 我做错什么了吗 编辑:C++ 通过posix套接字发送文件时的零窗口,c++,linux,tcp,sockets,posix,C++,Linux,Tcp,Sockets,Posix,我有一个问题——当我试图通过posix套接字发送大量数据(不管是文件还是一些数据)时,在某个时刻我没有收到我所期望的数据——我使用wireshark来确定是什么导致了错误,我发现,就在我的应用程序崩溃的时候,有标记为红色的数据包说“零窗口”或“零窗口”“窗口已满”向两个方向发送 结果是,应用程序层没有得到send()函数发送的一段数据 我做错什么了吗 编辑: 假设我想发送19232条数据,每条1024字节-在某个随机点(或者根本不发送)我得到的不是第9344个数据包,而是第9345个数据包。我没
假设我想发送19232条数据,每条1024字节-在某个随机点(或者根本不发送)我得到的不是第9344个数据包,而是第9345个数据包。我没有实现任何重传协议,因为我认为TCP是为我做的。在您的网络中,是否也无法发送如此数量的数据包?如果没有,请检查它们如何发送如此数量的数据。嗯,从我读到的这可能是某种缓冲区溢出(接收方报告接收窗口为零)。只是猜测一下。零窗口/窗口已满表示TCP连接的一端无法接收更多数据,直到其客户端应用程序读取到已接收的部分数据。换句话说,它是连接的一端告诉另一端”除非我告诉你,否则不要再发送任何数据” TCP确实处理重传。您的问题可能是:
send()
返回0
(未写入字节),或-1
,并将errno
设置为ewoodblock
send()
发送了您要求发送的所有数据这会导致数据丢失。您需要修复发送端,以便它处理
send()
失败,包括返回一个小于您要求它发送的字节数的值。如果套接字是非阻塞的,这意味着等待select()
在重试之前告诉您套接字是可写的。首先,TCP是一种字节流协议,而不是基于数据包的协议。仅仅因为您发送了1024字节的数据块,并不意味着它将以这种方式接收。如果您填充管道的速度足够快,从而获得零窗口条件(即,在接收缓冲区或发送缓冲区中没有更多的空间)那么很可能在某个时候,接收器代码一次读取的数据量远远超过“数据包”的大小
如果您没有特别请求非阻塞套接字,则send
和recv
都将以零窗口/窗口满状态阻塞,而不是返回错误
如果您想粘贴接收方代码,我们可以看一下,但是从您描述的内容来看,您的第9344次读取很可能实际得到的字节数超过了您的数据包大小。您是否检查了从
recv
返回的值?TCP应该为您这样做……您可以复制/通过部分代码吗?我已经尝试发送了/在4 FC8 x86系统上,使用socket,一个作为服务器,三个客户端接收巨大的文件(比如几GB,带有FILE64选项)。虽然我使用了应用程序级消息库Effo NetMsg()。如果使用TCP,则应用程序send()可以通过协议和send/recv缓冲区控制传输更大的数据包(意味着>MTU)。所以系统应该没有问题。