为什么select()返回1但recv()返回0?

Eni*_*gma 2 c++ windows networking select winsock2

我可以清楚地看到recvbuf所有数据都在我期望的范围内,但是select()一直返回1。

现在,它陷入了困境else if (iBuffer == 0) {}

SOCKET m_ConnectSocket;
/* The socket setup is done elsewhere but just adding this for clarity
   This socket is responsible for sending from the client to the server
   and also receives anything the server sends back.

   This socket is doing the connect() & initial send()
*/

fd_set set;
struct timeval timeout;

// Set up the file descriptor set.
FD_ZERO(&set);
FD_SET(m_ConnectSocket, &set);

// Set up the struct timeval for the timeout.
timeout.tv_sec  = RECV_DELAY_SEC;
timeout.tv_usec = RECV_DELAY_USEC;

int iBuffer = 0;

do
{
    iResult = select(m_ConnectSocket, &set, NULL, NULL, &timeout);
    if (iResult > 0)
    {
        iBuffer = recv(m_ConnectSocket, recvbuf, DEFAULT_BUFLEN, 0);
        if (iBuffer > 0)
        {
            string sRecv(recvbuf);

            STrace = String::Format("Bytes Received: {0}", iBuffer);
            Trace(STrace, TRACE_INFO);

            STrace = String::Format("Data Received: [{0}]", gcnew String(sRecv.c_str()));
            Trace(STrace, TRACE_INFO);
        }
        else if (iBuffer == 0)
        {
            STrace = String::Format("iBuffer empty");
            Trace(STrace, TRACE_INFO);
        }
        else
        {
            STrace = String::Format("recv failed: {0}", WSAGetLastError());
            Trace(STrace, TRACE_ERROR);
        }
    }
    else if (iResult == 0)
    {
        STrace = String::Format("No data left in buffer");
        Trace(STrace, TRACE_INFO);

        pMessage->Data(recvbuf);
        if (iSentType != pMessage->Type())
        {
            STrace = String::Format("Message type mismatch: {0} | Expected: {1}", (int)pMessage->Type(), (int)iSentType);
            Trace(STrace, TRACE_WARNING);
        }
    }
    else if (iResult == -1)
    {
        STrace = String::Format("select() error");
        Trace(STrace, TRACE_ERROR);
    }
} while (iResult > 0);
Run Code Online (Sandbox Code Playgroud)

use*_*421 5

到目前为止,所有答案都正确,说明了如何重置FD集,但是它们都没有真正识别出潜在的问题。

如果recv()返回零,则意味着对等方已断开连接,并且您必须关闭套接字。如果不这样做,那么您将继续选择该套接字为可读套接字,并继续接收零。

并不意味着“缓冲空”。