我有一个非常讨厌的问题,我在其他论坛上发现了几次,但我找不到合适的解决方案。 问题是recv()在连接的最后几个字节返回0。以下是一些背景信息。
我多次调用send()(小块),从客户端调用53个字节。 服务器多次调用recv()(4字节请求)并读取49个字节然后返回0(54字节 - 49字节,因此缺少4个字节)。
MSDN和一些论坛为非阻塞套接字编写:
MSDN也说:
使用带有SD_SEND或SD_BOTH的closesocket或shutdown函数 导致RELEASE信号在控制信道上发送出去。应有 ATM可以使用单独的信号和数据通道 RELEASE信号可以在最后一个之前到达远程端 数据到达目的地,导致数据丢失。一 可能的解决方案是在最后一个之间编程足够的延迟 发送的数据和closesocket或shutdown函数调用ATM 插座。
这在recv()和send()的示例中被视为:http://msdn.microsoft.com/en-us/library/windows/desktop/ms740121(v=vs.85).aspx
但仍然没有成功,在收到49字节后,我仍然在10%的连接中得到一些中断,90%的连接成功。有任何想法吗? THX。
答案 0 :(得分:11)
recv()
仅在您请求0字节缓冲区或其他对等方已正常断开连接时返回0。如果您没有收到所需的所有数据,那么您开始时并没有正确读取数据。请使用您的实际代码更新您的问题。
答案 1 :(得分:0)
我的猜测是你并没有真正发送你认为发送的所有数据。退房:
答案 2 :(得分:-1)
- 当另一端关闭连接时,recv()绝对返回= 0
这不是完全正确的,在以下使用非阻塞winsock2 tcp的代码中,当没有可用数据时,select返回1,recv返回0,WSAGetLastError()也是如此。
fd_set test = {1, socket};
const timeval timeout = {0, 0};
if (!::select(0, &test, nullptr, nullptr, &timeout)) return 0;
int done = ::recv(socket, buffer, 1, 0);
即使另一端呼叫后,这种情况仍会继续:
::shutdown(socket, SD_BOTH);
::closesocket(socket);
,然后结束。通讯正常进行,只是:: recv似乎“中断”。