1.首先TCP是长连接,连接后正常情况下是不会无故断开的,但是由于路由,以及防火墙等原因的存在,会踢出长时间没有数据交换的连接,所以要有一个保活机制,发送心跳包
或者设置
e.AcceptSocket.IOControl(IOControlCode.KeepAliveValues, _keepAliveOptions, null);
2.
a.在连接没有关闭的情况下客户端异常退出,服务端还要维持这样一个连接就比较浪费,所以要踢出;
b.踢出几分钟内没有交互的连接
问题:如何去理解这两种关系??
<一>
防火墙:
防火墙一般允许墙内主动向墙外发起连接,比如
10.10.10.10.1:1234 => 20.20.20.20:80
为了让返回的数据能够通过防火墙到达墙内,
防火墙要记住外出请求,并在一定时间内,允许20.20.20.20:80 =〉10.10.10.10.1:1234的内进数据通过。
因此,如果长时间内没有墙内到墙外的数据流量,防火墙可能就不再允许由外往内的数据。
也就是墙外服务器的通知,可能就会被来防火墙阻断。
<二>
IOControlCode.KeepAlive就是让Socket定时的传输一个TCP包。
该包没有用户数据,但对防火墙可以看到该TCP数据,以便重置空闲时间,保持对内进数据的开放。
是长连接中处理客户端异常断开的处理机制,断开后send等方法 无法顺利执行,某些属性属于异常
个人感觉KeepAlive 最主要的功能是 长连接中处理客户端异常断开的情况,当客户端已经关闭的时候继续傻傻地发送数据会抛出异常 ;
至于它的保活,就是客户端时常给服务端发送消息;
<三>
踢出,踢出时判断的对象是接收数据的时间LastReceiveDateTime或者是自己定义的LogTime,但都是接收到实际数据的时间,比如说6分钟内没有接收到实际d数据就踢出去
再补一个链接:
http://www.cnblogs.com/liuyong/archive/2011/07/01/2095487.html
这是社会主义精神文明和物质文明之间的关系,两手都要抓,两手都要硬。