当使用Winsock读取所有信息时,结束"recv()"循环

Rag*_*geD 6 c++ windows winapi winsock recv

我在winsock的recv()循环中遇到了问题.我试图在iResult == 0时终止循环,但是,循环仅在套接字关闭时结束.它似乎挂在最后一个recv(),其中iResult等于0.那么有关如何有效终止循环的任何想法?我的最终目标(无论iResult是否= 0;或许我的方法是错误的)是在读取所有发送的信息时停止循环.这是循环.

    do
    {
        iResult = recv(socket, recvbuf, BUFLEN-1, 0);
        if(iResult > 0){
            // Null byte :)
            // Remove that garbage >:(
            recvbuf[iResult] = '\0';
            printf("Recvbuf: %s\n\n\niResult: %d\n",recvbuf,iResult);
            continue; // working properly
        }
        else if(iResult == 0)
            // Connection closed properly
            break;
        else
        {
            printf("ERROR! %ld",WSAGetLastError());
            break;
        }
    } while(iResult > 0);
Run Code Online (Sandbox Code Playgroud)

就像我说的,我收到的所有数据,我都无法退出循环.下一步是将数据写回服务器,但它会挂起,直到ping超时.套接字是SOCK_STREAM,BUFLEN定义为0x200

谢谢

Dan*_*lau 3

默认情况下,recv 如果没有数据要接收,则阻塞,而不是返回 0 :

如果套接字上没有可用的传入数据,则根据为 WSARecv 定义的阻塞规则,recv 调用将阻塞并等待数据到达,除非套接字是非阻塞的,否则不会设置 MSG_PARTIAL 标志。在这种情况下,将返回 SOCKET_ERROR 值,并将错误代码设置为 WSAEWOULDBLOCK。select、WSAAsyncSelect 或 WSAEventSelect 函数可用于确定更多数据何时到达。

您可以使用ioctlsocket将套接字置于非阻塞模式:

u_long iMode = 1;
ioctlsocket(socket, FIONBIO, &iMode);
Run Code Online (Sandbox Code Playgroud)

编辑:这是我在早期版本中提出的setsockopt建议,然后删除(请参阅评论):

您可以使用setsockopt 函数,并选择SO_RCVTIMEO将套接字设置为recv 在没有可用数据时超时。