注册
登录
提问时间:2016/7/4 23:02:36
请问下:如果三次握手成功建立连接后,但是双方没有任何数据交流,也不主动关闭连接,那么这个连接是不是会一直存在下去,还是说tcp的实现有一个超时机制?
如果说一直存在,那么很显然可以用DDOS把一台服务器资源耗尽吧?
但是我好像没有找到设置超时的接口
(不是那种SO_RCVTIMEO之类的,这种应该是提供给用户层应用程序使用的选项)
1楼(站大爷用户)

tcp超时是由应用自己做的,应用要定时发心跳包,就类似一个看门狗,用心跳包喂狗,长时间不喂狗就会导致连接断开。

至于攻击,这实际上是一个cc攻击的例子,lz可以自行google
2楼(未知网友)

tcp自己的检测时间是2个小时,如果你要修改这个时间需要重新编译内核,但会对所有应用有影响。一般是需要自己实现心跳包的,不要依赖tcp的实现。
网络攻击的方式太多了,比如握手后一个字节一个字节发送数据,唤醒io读取。。。
3楼(未知网友)

TCP 虽然有 Keepalive,但它只有在连接有异常的时候才会关闭连接
具体来说,在 客户主机始终正常运行,并且从服务器端可达的 情况下,
TCP 的保活定时器会不断以固定的时间间隔(默认7200s)触发,发送探查报文
这种状况只能知道对方是正常的,并不会将连接关闭

而当客户端可能处于 已经崩溃、已经崩溃并重启了、由于中间链路问题不可达 的情况下时,
TCP 会将连接断开


防范 DDOS 的话,得应用层负责
4楼(站大爷用户)

三次握手成功后,如果双方不交流任何数据,网络也没有中断,任何一方程序或者机器都没有崩溃 ,那这个连接会一直持续下去。

至于TCP的KeepAlive(注意不要和http的KeepAlive混淆),它只负责定时发探测分节给对方,如果对方成功ACK,那说明连接正常 TCP是不会关闭这个连接的,也就是说,KeepAlive只在发现连接异常的时候才会放弃连接。这个行为在用户应用层程序是不得而知的。

至于题主提到的通过setsockopt函数设置的SO_RCVTIMEO/SO_SNDTIMEO选项,是在使用阻塞socket的时候, 设置读写被阻塞的超时时间,如果超过这个时间依然在阻塞中,没有完成读写socket的话,send/recv或者write/read将返回-1并设置errno为EAGAIN。这个设置,对TCP连接的生死是毫无影响的。

最后,题主想要的目的应该是如何避免长期无通信的闲置连接浪费系统资源。这个必须在应用层想办法解决,服务端需要主动关闭长期闲置连接。当确认某个连接长期闲置的时候,可以先用shutdown关闭写端,保证TCP发送缓存区的残余数据发送完毕,这时候TCP_FIN分节已经发送给对端。然后收到read返回0时close描述符。如果对方应TCP_FIN分节后由于bug故障或者恶意动机未能回应,也就是说只收到本端TCP_FIN分节的ACK未收到对端的TCP_FIN分节,需要强制措施,防止连接一直处于FIN_WAIT2状态(很多系统这个状态是没有超时机制的)。
立即注册站大爷用户,免费试用全部产品
立即注册站大爷用户,免费试用全部产品