当前位置: 技术问答>linux和unix
tcp连接中服务器如何知道客户端退出
来源: 互联网 发布时间:2015-07-25
本文导语: TCP是有连接的,所以不需要自己编写代码维持连接通道,但客户端正常或异常退出时,服务端如何知道?TCP协议中不是说关闭有几个握手吗?是不是需要在服务端调用这个握手?如何调用? | ...
TCP是有连接的,所以不需要自己编写代码维持连接通道,但客户端正常或异常退出时,服务端如何知道?TCP协议中不是说关闭有几个握手吗?是不是需要在服务端调用这个握手?如何调用?
|
正常地断开tcp连接才有握手过程。
但在异常地状况下,如客户端突然断电等,
服务器是无法得知客户端断开。
因此很多异常状况下服务器/客户端只有自己检测对方是否异常中止。
方法有很多,
比如server阻塞于read调用,而client没有连接情况下
经过一段时间会返回ETIMEDOUT,和ehostunreach等错误,
具体的错误要看TCP连接的异常状况
但在异常地状况下,如客户端突然断电等,
服务器是无法得知客户端断开。
因此很多异常状况下服务器/客户端只有自己检测对方是否异常中止。
方法有很多,
比如server阻塞于read调用,而client没有连接情况下
经过一段时间会返回ETIMEDOUT,和ehostunreach等错误,
具体的错误要看TCP连接的异常状况
|
如ExitWin(ExitWin)所说,自定义链路检测包是个可以方便控制的方法。
比如
3分钟没有数据传输,即触发链路检测,
1次:未接收到响应包,1分钟后重发;
2次:未接收到响应包,1分钟后重发;
3次:未接收到响应包,1分钟后重发;
确认连接丢失,断开当前连接,尝试重连。
比如
3分钟没有数据传输,即触发链路检测,
1次:未接收到响应包,1分钟后重发;
2次:未接收到响应包,1分钟后重发;
3次:未接收到响应包,1分钟后重发;
确认连接丢失,断开当前连接,尝试重连。
|
SO_KEEPALIVE
该选项可以在socket长时间没有数据发送接收的情况下发送特别的包以确定对方存在
但是需要的时间比较长,通常用在服务器上,发3次,一次间隔比一次长,3次没有响应则认为对方已经不存在,这时候读操作将立即返回告知对方已关闭
所需的时间大概是1-2小时(因此不适合想立即知道的情况)
该选项可以在socket长时间没有数据发送接收的情况下发送特别的包以确定对方存在
但是需要的时间比较长,通常用在服务器上,发3次,一次间隔比一次长,3次没有响应则认为对方已经不存在,这时候读操作将立即返回告知对方已关闭
所需的时间大概是1-2小时(因此不适合想立即知道的情况)
|
Try to read/write the socket and check if the result is less than 0.
|
在不发送数据包检测的情况下
还可以通过 SOCKET选项来实现
如给套接口设定SO_KEEPALIVE
还可以通过 SOCKET选项来实现
如给套接口设定SO_KEEPALIVE
|
自己定义一个心跳来监控客户端就可以了
|
一个简单的办法,你可以设置超时。