socket用异步消息方式通信,我们知道在客户端socket关闭时,server端socket会收到FD_CLOSE消息,可是如果客户端是非正常关闭的话,服务器端就不知道该连接是不是还在,也就是说不能通过消息来及时知道socket的状态。我一般有两种做法,一种就是socket创建后,和客户端按照一定时间间隔发测试包,如果有几次(自己设定)没有收到测试包,则认为和客户端的连接已经断了,关闭对应socket.方法二:在服务器端按照一定时间间隔(定时)判断各个连接是否已经断了,如果是则关闭对应socket。不知道大家是怎么处理这个问题的?

解决方案 »

  1.   

    tcp/ip是基于连接的通讯,如果网络异常断开,通讯双方更本就无法知道,只有等到任何一方发送数据失败,而且重试3次之后,tcp/ip才可以认为断开了。
    我一般用icmp模拟ping的操作来判断网络是否正常
      

  2.   

    int sdin = SOCKET HANDLEif(HasConnectionDropped(sdin)){
       //丢了
    }BOOL HasConnectionDropped(int sdin)
    {
    BOOL bConnDropped = FALSE;
    INT iRet = 0;
    BOOL bOK = TRUE;

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

    FD_ZERO(&readSocketSet);
    FD_SET(sdin, &readSocketSet);

    iRet = ::select(0, &readSocketSet, NULL, NULL, &timeout);
    bOK = (iRet > 0);

    if(bOK)
    {
    bOK = FD_ISSET(sdin, &readSocketSet);
    }

    if(bOK)
    {
    CHAR szBuffer[1] = "";
    iRet = ::recv(sdin, szBuffer, 1, MSG_PEEK);
    bOK = (iRet > 0);
    if(!bOK)
    {
    INT iError = ::WSAGetLastError();
    bConnDropped = (( iError == WSAENETRESET) ||
    (iError == WSAECONNABORTED) ||
    (iError == WSAECONNRESET) ||
    (iError == WSAEINVAL) ||
    (iRet == 0));
    }
    }
        return(bConnDropped);
    }
      

  3.   

    GetTcpTable也可以实现这个功能
      

  4.   

    同意 Crob观点。
    用select函数判断。
      

  5.   

    用select函数的的第四个参数判断
      

  6.   

    一般是通过用UDP发心跳包  但这种办法对于故障时间很短的异常关闭来说有缺陷  这时可以用TCP发心跳包 但这样一来增加了服务器的负荷。各有利弊
      

  7.   

    不能ping啊,大家试试ping www.csdn.net
      

  8.   

    GetTcpTable () function 怎么使用啊? 有人可以给出一个例子吗?