可以通过客户端给服务器发心跳包,比如心跳30s一次,如果超过一分钟没收到心跳包就将这个链接close掉。

解决方案 »

  1.   

    你这个“四次握手”是怎么来的?底层的握手应该是三次的啊,哪来的四次?
    1、C 告诉 S 我要连接,你收到我的请求了吗?( C 调用 connect )
    2、S 收到请求后批准 C 的连接,并且告诉 C 我收到你的请求了,你收到我的反馈了吗?
    3、C 收到 S 的反馈后再告诉 S 我收到你的反馈了,我已经准备收发数据了。S 收到 C 的消息后不再发消息给 C,只是告诉应用层已经可以给 C 收发数据了(acceep 通知)如果是你自己写的协议,那么就证明客户端已经正常连接上了,只是后来其它原因导致掉线
    这个还好解决,服务端另开一条线程,检测每个连接最近一次的数据传输是否超过设定值,如果超过则断了它
    当然客户端也要开条线程,每过一段时间检测于服务器数据传输是否超过设定值,如果超过则发个心跳包给服务器
    客户端的设定值要比服务端设置的短另外一种情况,你所说的 closesocket 没用,那就说明客户端没有正常连接上了
    你所说的握手没有完成,是底层 tcp 没有完成三次握手(不是四次的)不过你自己也不清楚是什么状况,看看服务器拒绝连接的时候给的是什么错误
    (服务端查看 acceep 返回的错误、客户端也要查看 connect 返回的错误)排除被攻击的情况后,只能说明你的网络状况太差了
      

  2.   

    lz说的应该是正常closesocket产生的四次挥手。
      

  3.   

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters]
    "TcpTimedWaitDelay"=dword:0000001e试试看。
      

  4.   

    问题是客户端在没有正常close情况下就自动重启了,这时服务器端还有这个链接,我现在就是判断一定时间没有传递数据后,就close服务器端的tcp,但结果并没有释放资源;
      

  5.   

    你说的很对,原因就是网络太差,导致服务器端与客户端断开而无法传递数据,那么我就要释放服务器端的资源,这个时候应该怎么释放?是一定时间后closesocket呢还是其它方法?问题是我在服务器端测试定时内没有传递数据就close,但是发现并没有释放资源;
      

  6.   

    我在服务器端测试定时内没有传递数据就close,但是发现并没有释放资源;TCP为了通讯双方都能释放资源, closesocket会告诉对方自己close, 网络不良就会导致closesocket延迟一段时间再释放
      

  7.   

    如果客户端没有正常close情况下,突然重新启动,那么服务器端close后会释放资源吗?
      

  8.   

    会的, 网络不良, 断点重启等会导致 closesocket 延时释放, 如果没法释放那就是TCP明显的Bug了
      

  9.   

    是的, 相关情况你可以参考下这个选项SO_LINGER, 这种是针对TIME_WAIT状态的
    established的需要心跳包, 可以参考SIO_KEEPALIVE_VALS
      

  10.   

    服务器端定时发送测试包就可以了。
    原理是:TCP不轮询,需要触发