问题解决,立即给分。
本人手头总共20分,全给了。
希望能给一段代码。
谢谢了

解决方案 »

  1.   

    CCrobSocket是一个CSocket的派生类
    在当IsConnectionLost返回True时,说明当前的SOCKET连接已经失效了。
    m_hSocket是当前SOCKET连接的句柄BOOL CCrobSocket::IsConnectionLost()
    {
    BOOL bConnLost = FALSE;
    int nRet = 0;
    BOOL bOK = TRUE;

    if (m_hSocket == INVALID_SOCKET)
    return TRUE; struct timeval timeout = { 0, 0 };
    fd_set rset;

    FD_ZERO(&rset);
    FD_SET(m_hSocket, &rset);

    nRet = ::select(0, &rset, NULL, NULL, &timeout);
    bOK = (nRet > 0);

    if(bOK)
    {
    bOK = FD_ISSET(m_hSocket, &rset);
    }

    if(bOK)
    {
    char szBuffer[1] = "";
    nRet = ::recv(m_hSocket, szBuffer, 1, MSG_PEEK);
    bOK = (nRet > 0);
    if(!bOK)
    {
    int err = ::WSAGetLastError();
    bConnLost = (( err == WSAENETRESET) || (err == WSAECONNABORTED) || (err == WSAECONNRESET) || (err == WSAEINVAL) || (nRet == 0));
    }
    }
        return(bConnLost);
    }
      

  2.   

    楼上用的是偷窥数据的方法,我用的是keepalive的方法,缺点是不支持win98。
    下面的例子是tcp/ip阻塞的socket.能够监测到电脑reset或拔掉网线后socket中断的情况!//server
    /***********************************************
    command format: TCPTest port, 
    for example: 
    TCPTest 5678
    ************************************************/
    //    This function is called as a thread, and it handles a given
    //    client connection.  The parameter passed in is the socket 
    //    handle returned from an accept() call.  This function calls
    //    a socket api function to detect whether the client is online.
    //
    DWORD WINAPI ClientThread(LPVOID lpParam)
    {
        SOCKET sock = (SOCKET)lpParam;
        char szBuff[DEFAULT_BUFFER];

        while(1)
        {
    //call a socket function to detect whether the client is online.
            int ret = recv(sock, szBuff, DEFAULT_BUFFER, 0); //check the returned value
            if(WSAGetLastError() == WSAENETRESET)//The connection has been broken 
      //due to the keep-alive activity 
      //detecting a failure while the 
      //operation was in progress
    {
    printf("client WSAENETRESET!, sock = %d\n", sock);
    shutdown(sock, SD_BOTH);
    closesocket(sock);
                break;
    }
            if(WSAGetLastError() == WSAENOTCONN)//The socket is not connected.
    {
    printf("client WSAENOTCONN!, sock = %d\n", sock);
    shutdown(sock, SD_BOTH);
    closesocket(sock);
                break;
    }
    if(WSAGetLastError() == WSAECONNRESET)//The virtual circuit was reset by the 
      //remote side executing a hard or abortive 
      //close. The application should close the 
      //socket as it is no longer usable. On a 
      //UPD-datagram socket this error would 
      //indicate that a previous send operation 
      //resulted in an ICMP "Port Unreachable" 
      //message.
    {
    printf("client WSAECONNRESET!, sock = %d\n", sock);
    shutdown(sock, SD_BOTH);
    closesocket(sock);
                break;
    }
        else if(ret == SOCKET_ERROR)
            {
    continue;
            }
    //Sleep(10);
        }
        return 0;
    }int main(int argc, char* argv[])
    {
    ///////////////////////////////////////////// int nPort;
    if(argc == 1)
    nPort = DEFAULT_PORT;
    else
    nPort = atoi(argv[1]); /////////////////////////////////////////    WSADATA       wsd;
        SOCKET        sListen,
                      sClient;
        int           iAddrSize;
        HANDLE        hThread;
        DWORD         dwThreadId;
        struct sockaddr_in local,
                           client;    if(WSAStartup(MAKEWORD(2,2), &wsd) != 0)
        {
            printf("Failed to load Winsock!\n");
            return 1;
        }
        // Create a listen socket
        sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
        if (sListen == SOCKET_ERROR)
        {
            printf("socket() failed: %d\n", WSAGetLastError());
    WSACleanup();
            return 1;
        }    // Select the local interface and bind to it
    local.sin_addr.s_addr = htonl(INADDR_ANY);
        local.sin_family = AF_INET;
        local.sin_port = htons(nPort);    if (bind(sListen, (struct sockaddr *)&local, 
                sizeof(local)) == SOCKET_ERROR)
        {
            printf("bind() failed: %d\n", WSAGetLastError());
    closesocket(sListen);
        
    WSACleanup();
            return 1;
        } //set KeepAlive
    struct tcp_keepalive kp;
    kp.onoff = 1;
    kp.keepalivetime = 100;
    kp.keepaliveinterval = 100; DWORD cbRet;
    if( 0 != WSAIoctl(
      sListen,
      SIO_KEEPALIVE_VALS,                                                    
      &kp,                             
      sizeof(kp),                           
      NULL,
      0,
      &cbRet,
      NULL,
      NULL
      ))
    {
    closesocket(sListen);
    WSACleanup();
    return 1;
    }    listen(sListen, 8);
    printf("listening...\n");
        
        // In a continous loop, wait for incoming clients. Once one 
        // is detected, create a thread and pass the handle off to it.
        iAddrSize = sizeof(client);
        while(1)
        {
            sClient = accept(sListen, (struct sockaddr *)&client,
                            &iAddrSize);        if (sClient == INVALID_SOCKET)
            {        
                //printf("accept() failed: %d\n", WSAGetLastError());
    continue;
            }
            printf("Accepted client: %s:%d\n", 
                inet_ntoa(client.sin_addr), ntohs(client.sin_port));
    hThread = CreateThread(NULL, 0, ClientThread, 
                        (LPVOID)sClient, 0, &dwThreadId);        if (hThread == NULL)
            {
                printf("CreateThread() failed: %d\n", GetLastError());
    closesocket(sClient);
                continue;
            }
            CloseHandle(hThread);

        }    closesocket(sListen);
        
        WSACleanup();

    return 0;
    }