TCP热点知识回顾

TCP 四元组:源IP,源端口,目标Ip,目标端口

TCP连接有十一中状态:closed,established,listen,time_wait,closing等
https://blog.csdn.net/zimou5581/article/details/78939186

TCP连接的多种状态,TCP的三次握手和四次挥手。
https://www.cnblogs.com/bj-mr-li/p/11106390.html

三次握手

四次挥手

第三次握手失败会怎样?

如果第三次握手迟迟不来,服务端就可以识别第一个SYN是无效的,就会将线程内存资源释放。但是在释放之前,会重发ACK数据。
还有一种情况就是第三次握手失败,但是客户端认为自己已经连接好了,就会给服务端发送数据,服务端由于没有收到第三次握手,就会以RST包对客户端响应,收到RST的的客户端就知道第三次握手没有成功,会重新发起握手连接。
如何防御SYN拒绝服务攻击:1.降低SYN timeout 的时间;;2.连续收到某IP的大量SYN请求时,通过防火墙进行拦截;3.如果是通过域名解析来攻击的,可以通过修改DNS,将域名解析改到新的IP地址。

为什么连接的时候是三次握手,关闭的时候却是四次握手?

TCP是全双工的可靠信道,两端都可以同时写数据。因此挥手需要两端都确认没有数据需要发送了。
OpenSSL是半双工的,收和发之间需要加互斥锁,二者不能同时工作。(单工就是只能单向地发)

关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你未必会马上会关闭SOCKET,也即可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。

为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。

假设 TIME-WAIT 没有等待时间或时间过短,断开连接会造成什么问题呢?

TIME_WAIT一定是发生在主动关闭的一方;

TIME-WAIT 作⽤是等待足够的时间以确保最后的 ACK 能让被动关闭方接收,从而帮助其正常关闭。

主动断开的一方等待时间过短,则对端可能会一直重发FIN,因为一直未收到ACK确认消息。

服务端大量的TIME_WAIT会导致什么问题?

在某些场景下,60 秒的等待销毁时间确实是难以接受的,例如:高并发的压力测试,或者大量的短连接HTTP请求出现,本地就可能产生大量处于 TIME_WAIT 状态的 TCP 连接。如果客户端等待的时间不够长,那么使用相同端口号重新与远程建立连接时会造成以下问题:

  1. 因为客户端发出的 ACK 可能还没有被服务端接收,服务端可能还处于 LAST_ACK 状态,所以它会回复 RST 消息终止新连接的建立;
  2. 因为数据段的网络传输时间不确定,所以可能会收到上一次 TCP 连接中未被收到的数据段;

为什么不能用两次握手进行连接?

答:3次握手完成两个重要的功能,既要双方做好发送数据的准备工作,双方都要知道自己和对方准备好了),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。

TCP传递的是数据流,流数据必须要有一个数据头,才能确定包的长度和数据偏移。

如果已经建立了连接,但是客户端突然出现故障了怎么办?

TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

进程被kill的时候,会对所有已经打开的文件描述符执行close。

TCP协议的KeepAlive保活机制会自动的在规定时间内向对端发送心跳包,Keepalive不是TCP标准规范。开启KeepAlive功能需要消耗额外的宽带和流量,所以TCP协议层协议规定默认是不开启的,默认的KeepAlive超时不能低于2小时。KeepAlive设置不合理的话有可能会,因为短暂的网络波动而断开健康的TCP连接。一般在应用层自己实现心跳包,方便控制。

KCP的发送机制
https://www.cnblogs.com/yuanyifei1/p/6846310.html

KCP是一个快速可靠协议,能以比 TCP浪费10%-20%的带宽的代价,换取平均延迟降低 30%-40%,且最大延迟降低三倍的传输效果。

KCP底层通过UDP,通过在应用层实现滑动窗口和消息保序,实现消息的可靠和有序。

UDP是不可靠信道,没有连接建立和断开的挥手过程。需要的时候直接发数据,不需要的时候就不发了。靠应用层心跳检测连接是否存在。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 using1174@foxmail.com

文章标题: TCP热点知识回顾

文章字数: 1,692

本文作者: Jun

发布时间: 2022-03-14, 15:34:00

最后更新: 2022-04-25, 14:50:11

原始链接: http://yoursite.com/2022/03/14/TCP热点知识回顾/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏