TCP C/S方式中,如果一端closesocket(h)了,另一方如何检测到对应的套接字句柄已关闭了(非阻塞方式)?是不是 recv()返回<0, 同时GetLastError()=0?

解决方案 »

  1.   

    recv()返回0,GetLastError返回的不是0,是WSAESHUTDOWN。
      

  2.   

    recv()=0
    WSAGetLastError返回的不是0
      

  3.   

    记得recv返回0就是Socekt关闭,-1是出错了用WSAGetLastError得到ErrorCode
      

  4.   

    csdn 上说:
    If no error occurs, recv returns the number of bytes received. If the connection has been gracefully closed, the return value is zero.这里的关闭是本地关闭还是对方关闭?我用的是非阻塞方式的,即每次有没有数据可以接收需要我自己查询一下(select),
    /*****************************************************/
    int Receive(SOCKET hTcpSocket, CHAR *buffer, int length, int nTimeOut)
    {
        int    iRecvStatus=0;
        nRecvBytes = 0 ;
        while ( nRecvBytes < length )
        {
            if ( Test(hTcpSocket, READ, nTimeOut ) == FALSE )
            {
                TRACE("TcpSocket %d now is not ready for recving, %d bytes recved , error             code %d\n", hTcpSocket, nRecvBytes, nSocketError);
                return sWAITING;
            }
            if ( (iRecvStatus = recv(hTcpSocket, buffer + nRecvBytes, length - nRecvBytes,     0 )) <= 0 )
            {
                nSocketError = WSAGetLastError();
                TRACE("TcpSocket %d recv failed, error code %d, %d bytes recved\n",             hTcpSocket, nSocketError, nRecvBytes);
                return sERROR;
            }
            nRecvBytes += iRecvStatus ;
        }
        return nRecvBytes ;
    }
    /*****************************************************/
    BOOL Test(SOCKET hSocket, EVENT e, int iTimeOut)
    {
    int nReadSocket = 0 ;
    fd_set sockSet;
    struct timeval interval; FD_ZERO(&sockSet);
    FD_SET(hSocket, &sockSet);
    interval.tv_sec  = iTimeOut;
    interval.tv_usec = (iTimeOut > 0) ? 0 : 10;
    if ( e == READ )
    return ( nReadSocket = select(0, &sockSet, NULL, NULL, &interval));
    else if ( e == WRITE )
    return ( nReadSocket = select(0, NULL, &sockSet, NULL, &interval) );
    return (nReadSocket == 1);
    }
    现在我发现,如果对方关闭了连接,则本地的 test返回一直为false,因为
    select(0, &sockSet, NULL, NULL, &interval) 返回不为1,就是说没有 套接字里有数据 可以被接收了.所以test下面的 recv也不会执行了, 那我怎么判断呢?
      

  5.   

    recv()返回0,GetLastError返回的是0。
      

  6.   


      用WSAAsyncSelect()函数,让套接字关闭的时候给某个窗口发送某个消息。或者:
     
      用 WSAEventSelect(),让套接字关闭时使某个事件处于有信号状态。
      

  7.   

    是吗?是不是 非阻塞方式的socket使用select有问题?
      

  8.   

    closesocket(hSocket);
    hSocket=INVALID_SOCKET;//
    然后每次都判断一下hSocket就行了
      

  9.   

    recv返回0,表示对方已经关闭套接字
    recv返回-1,如果 GetLastError() != 10035 的话... 
    用VC的errorlookup看一下错误代码吧!基本上可以关掉了如果不想用recv就用select,最好先select,套接字有事情发生(数据到来/套接字关闭)会返回的,然后recv
      

  10.   

    Why not use recv to see if the connection is closed directly,why use a select model
    to test the connection.  Throught the return value and the GetLastError() would be suffice if you only wanna get the connection status.