我遇到了recv()和send()winsock api的问题。收到最后一个数据包后,Recv()会挂起。
问题描述: -
系统A的应用程序通过非阻塞套接字写入数据,系统B的应用程序通过阻塞套接字以64k的块为单位接收数据。
似乎在读取64k的最后一个数据包(可能小于或等于64k)时,接收冻结了。我不确定最后一个数据包的接收或最后一个数据包的发送是否有问题,但我在遗留应用程序中间歇性地观察到这个问题。
之前有没有人遇到过类似的问题?如果是,那么请提供您的意见。
如果没有,那么请你提供一些故障排除技术来缩小根本原因。
仅供参考,我有win2k3服务器。
谢谢, VARUN
答案 0 :(得分:3)
Wireshark是排除网络代码故障的绝佳工具。它会准确地向您显示数据包进入和离开您的网络接口的时间。
至于你的具体问题:你是说最后一块数据可能短于64k?如果是这样,您的协议应包括一些消息长度信息,以便接收者 知道要查找多少数据。
答案 1 :(得分:1)
几个猜测......
如果您正在使用UDP,则可能会在途中丢弃一个或多个数据包(只要感觉到UDP就允许执行此操作)。在这种情况下,您的接收器可能最终会等待根本不会到达的数据;为了解决这个问题,您需要实现某种方式自动重新发送丢失的数据,或者(如果您不严格需要所有数据),发送者通过某种方式通知接收者他已完成传输,因此接收者不妨停止等待。 (当然,您需要处理此通知被删除的情况,如果您想要100%的稳健性,它会变得复杂)
如果您正在使用TCP,或许您没有仔细检查send()在发送方返回的值?如果你假设send()总是发送你要求它的字节数,你可能最终认为send()发送了所有的字节,实际上它只发送了一些(或没有)...所以发送方会认为传输已完成,而接收方将等待无法到达的数据。
答案 2 :(得分:0)
您可能遇到服务器发送数据的速度比接收器能够读取数据的速度快的问题。您可以尝试增加接收缓冲区:
int nSocketBuffer = 131072; // 128k
if (setsockopt(m_sSocket,SOL_SOCKET,SO_RCVBUF,(LPCSTR)&nSocketBuffer,sizeof(int)) == SOCKET_ERROR)
{
// socket error
return false;
}