1
rrfeng 2013-11-10 18:43:23 +08:00
维持?
如果互不发送数据,那么空闲超时计时器就起作用了,会认为链接已经断开。 本身好象是不会发送维持状态的包的,应用里自己写一个,10s hello 一次之类的…… |
2
wy315700 2013-11-10 19:06:13 +08:00
发的心跳包吧
|
3
damngood 2013-11-10 19:48:15 +08:00
应该是不会的, 不过最好还是在应用级别实现 心跳/ping 之类的机制来确认连接性
记得是说像 NAT 之类的设备会主动关闭有一段时间没有活跃了的连接.. |
4
akira 2013-11-10 20:04:13 +08:00
主动发下心跳包就好了。
|
5
go 2013-11-10 20:11:19 +08:00
一般就是心跳机制
|
6
lehui99 2013-11-10 20:51:05 +08:00
tcp本身的默认设置是没有心跳包的,不发数据则不会有任何数据包发送出去。所以一些tcp/ip协议的书(比如《TCP/IP协议详解》)中通常会有一个比较经典的例子:
一个tcp连接建立之后没有任何数据发送,两个终端之间的路由器(当然不能是终端直连的那个)断电了无数次,甚至有长达几天的断电,终端还无感知,几个月后这个tcp连接仍旧建立着。 之后一个终端突然断电了,另一个终端仍旧无感知,查看tcp状态还是established。 tcp的解决方法是设置keepalive,隔一段时间会发心跳包。当然这是可选的,默认是不打开的设置。 |
9
lehui99 2013-11-11 10:03:37 +08:00 via Android
楼上说的就是我说的keepalive选项
|
10
g0t3n OP @yfdyh000 设置 keepalive 会引起全局tcp连接都发送心跳包。所以如ssh什么得都会自己实现心跳包。不过其实我的问题应该是: 除了keepalive外,tcp建立连接后还会发送其他什么包来维持/传输数据吗?
|
11
tywtyw2002 2013-11-11 11:45:09 +08:00
@g0t3n tcp不去检查连接状态。
看看rfc吧,实在不行看 tcpip详解。。。。 生存检查都是上层协议干的(程序) 你说的这个tcp连接维持有些类似,udp的丢包检测。udp本身不去做丢包检测,是上层协议去管的丢包检测。 tcp也一样,tcp自己不去管,但是上层去管。 @lehui99 的例子不错,只要2个主机不挂,中间的网络挂了n次,那么tcp连接也不会中断。 以ssh为例,如果电脑从休眠恢复过来,ssh client的tcp连接还是established,如果这时候按回车,程序会按照原来的tcpip序列号去和服务器端进行交涉。注意这时的sport和src都是不变的,如果有公网ip,并且没有设置keepalive,这个连接还会继续的。 但是现在的网络环境都是nat。nat默认30分钟没有活动自动删除端口。所以这是如如果用的是内网ip,那么肯定无法连接了,因为sport改了,再去连服务器,回来的肯定是rst了。收到rst后,ssh客户端就会认为连接关闭了。。。 其次还有如果ip变换了,主机上类似的操作就是把网卡down掉,在up一下,这个操作会吧tcpip协议栈清空。 |
12
lehui99 2013-11-11 15:28:05 +08:00 via Android
@tywtyw2002 说的不错,如果终端之间不存在nat,那么几个月后双方仍旧可以正常通讯。可以说是nat破坏了tcpip的rfc规范,不过这也是没办法才这样的
|
13
tywtyw2002 2013-11-12 13:31:00 +08:00
@lehui99 其实nat特没破坏,破换是因为多内网ip对一个公网ip。
我在学校有台服务器是内网地址,然后网关处nat倒唯一一个ipv4地址,这种情况也没有断掉。 断掉还是因为 nat设备清了nathash表 |
14
lehui99 2013-11-12 21:22:39 +08:00
@tywtyw2002 嗯,我指的是一种nat(snat),不是说所有的nat都是
|