0. 如何理解tcp握手的设计
Last updated
Was this helpful?
Last updated
Was this helpful?
(长话短说)为什么三次握手呢? 四次不说了, 因为你总是可以用更多的通话次数交流等量的信息. 而两次会是什么情况? 因为TCP报文里没有一个表示时间的字段:
这种设计导致我无从得知这个包是什么时候发出的, 你拿到这个syn包的时候只能选择接受与不接受.
如果对方发完syn包人就撤了, 或者这个包出于某种原因游荡太久才抵达, 对方看你没响应人撤了, 总之这个会话端口就是关了. 而你选择接受并进入established就绪状态, 最后就变成你在这里空等着的场面了. 利用这种特点我就可以让你开一大堆没用的session, 浪费你的资源.
但如果我们有第三次确认, 我等不到你人还在的确认, 默认60秒之后断开连接
但这种方式并不是万能的, 至少我能耗你60秒对吗? 这就够了具备这种特点我可以找一大堆肉鸡, 或者一台机器开无数端口让你maintain一大堆 syn-recv 的连接, 然后你的服务器基本就处于无法提供服务的状态 (瘫痪了就是), 假设现在东西卖的很便宜, 我想买但是我不让你买, 那我就令服务器上的链接除了我以外都是肉鸡, 60秒够了
我们可以通过netstat的方式看看现在挂了多少个连接, 分别处于什么状态, 如果能发现一大堆sync-recv基本就可以断言了, 因为正常情况下这种状态很快就会被就绪态覆盖掉了, 想要处理掉这种情况, 你可以把时间改短一点, 或者增长rcvd队列
两段: TCP是双向聊天的(双工的), 终结一个session需要双方都完事, 每一段都是(FIN,ACK)的pair . 每一个wait节点都标注了自己在等待 (想要得到) 什么
一个常见的问题是为什么需要TIMEWAIT以及为什么时长是2MSL:
如果没有TIMEWAIT: 那么客户端也立刻终止这个端口, 稍后这个端口被拿来重新使用重新连接服务器, 如果这个时候一个服务器的包现在才到, 那么上一个session的包就进入了这次session
如果没有TIMEWAIT: 那么你发完就关闭了, 而这个ACK包服务器却没收到, 那么服务器就卡在最后一个环节了, 等一会如果服务器没有收到最后一个ACK包, 它会重发FIN包的
如果TIMEWAIT不是2MSL: 还是刚刚那个场景, 一个包在网络上飘荡的时间最长是2MSL, 如果你的TIMEWAIT小于2MSL那么同样可能接到这个包