当前位置:网站首页>TCP详解(一)
TCP详解(一)
2022-07-31 02:58:00 【爪哇菜鸡@】
TCP
TCP报头/首部(header)
首部是四位长度,单位不是字节,而是4个字节。
选项之前的20个字节是一定有的,首部最长是(1111 -> 15)也就是15 * 4 = 60字节。
选项部分范围就是0 ~ 40字节。
首部长度,其实就是划分了header和payload之前的分界线。
保留位:先占个位置,虽然暂时不用,保不齐以后可能会用。
关于TCP的特性
直观上看待TCP的特点
1.有连接
2.可靠传输
3.面向字节流
4.全双工
可靠性(TCP的核心特性)!!
尤其是要区分可靠性和安全性,TCP是可靠的,但是安不安全另当别论。
保证可靠性的核心:确认应答
1.确认应答(ACK)
发送方放松数据给接收方了,接收方就回应一个应答报文,如果发送方收到了这个应答报文,那么认为就是对方已经收到了。
由于网络上的传输,顺序是不确定的,因此就不能单纯的通过收到数据的顺序来确定逻辑,就需要对应大进行编号。
实际上,TCP传输数据不论条,而是论字节(面向字节流)
TCP的序号和确认序号,是以字节为单位进行编号的。
针对每个字节,分别编号,以此进行累加(实习上TCP的序列号的其实不一定是从1开始的)
确认序号和序列号之间的关系
第一个请求,A给B发送了1000字节的数据,徐浩就是1-1000(假设从1就开始编号了),这个操作就相当于发了一个TCP数据报,这个数据报的序号是1,长度是1000.
确认应答数据报,里面的确认序号是1001,意思就是1001之前的数据,B已经收到了。
发送方就可以根据确认单应答报文来确定接收方是否是收到了,只要发送方搜狐当了应答,就认为解说房已经收到,可靠性传输就完成了。
TCP的核心是可靠性,可靠性的核心是确认应答。
2.超时重传
确认应答机制中,这个是比较顺利的情况,但是传输过程中还是可能出现丢包的。
一旦发生数据丢包,就要进入超时重传的机制中了。
实际场景中,比如发消息没收到回复。
此时存在两种可能:
1.发的消息过去了,但是丢了,对方没看见
2.我发的消息过去了,对方看见了,也恢复了,但是回复消息的时候丢了
发送方无法区分,当前是发的数据丢了,还是应答数据丢了。
发送方能做的事情,只是在一段时间之后,重新发送一条数据。
解决方案
发送方把数据发出去之后,等待500ms,若是没有收到应答,就认为是丢包了。
超时时间会动态变化,不是一成不变的。
不同场景等待时间不同,等待时间会逐渐延,延长时间也是意味着让数据重传的频率降低。重传还是失败,大概率传输是不通了。
3.连接管理(重点)
TCP是有连接的,连接管理说的就是,如何建立连接(三四握手),如何断开连接(四次挥手)。、
三次握手(建立连接)
举个生动形象的例子,比如我想向女神表白,为了表达我的爱慕之意,给女神写了一封情书,女神同意了。
此时这个②过程表示两层含义,一层是接收到了我的爱慕表达,一层是也像我表达了爱慕之意
这样一来,男女朋友关系就建立了~
但是在TCP协议中实际的含义是如下这样:
谈谈三次握手的过程(画图)
本质上,就是,A向B请求连接,B给与回应.B也向A请求连接,A也给与回应
本来应该是"四次握手"
但是中间两次操作,是可以合在一起的,这两个操作在时间上是同时发生的
当A的syn 到达B的时候,B的内核就会第一时间进行应答ACK,同时也会第一时间发起SYN.这两件事同时触发,于是就没必要分成两次传输,直接一步到位
为啥要三次握手,为啥要建立连接?
主要目的是有两个:
1.投石问路:通过三次握手的过程,来确认A和B之间的传输是通畅的。尤其是要确认,A和B各自的发送能力和接受能力是否正常。
2.协商参数,通过三次握手。让A和B之间通通气,选择一些传输中合适的参数,例如。TCP的序列号从几开始。
举个例子:想象打电话的过程
延伸的问题:
为什么是三次握手不是四次握手。两次行不行?
可以四次握手,但是完全没必要,中间的ACK和SYn是可以合并在一起的,如果分成两个,传输的开销要比第一个大,涉及到封装和分用,效率上略低一点。
但是不能两次握手,这样不能知道A的接受能力和发送ACK是否正常,就相当于打电话A没有回应B,不知道是A的听筒坏了还是麦克风坏了。
TCP是有状态的
重点掌握的状态:
1.LISTEN:类似手机开机,信号满格,可以随时打入电话,服务器的状态。当我们创 建好ServerSocket实例的时候就进入了LISTEN状态。
2.ESTABLISHED:类似接通了电话,双方开始进行通话了,代码中accept返回了,得 到了一个clientSocket。
四次挥手(断开连接)
我们之前说三次握手,很明显我们知道A是客户端,B是服务器,客户端是主动的,服务器是被动的。
但是在四次挥手中,客户端和服务器都可以主动断开连接。
FIN是结束报文段
针对上图中的ACK和FIN为啥不能合并?
对于 B 来说,ACK 和 FIN 的出发时机是不一样的。
1.B 只要搜狐到 FIN 就会立即触发 ACK ,这个是内核态完成的。
2.B 发送的FIN 实际是用户代码控制的,代码中出现了
socket.close()
这样的操作的时候,才会触发 FIN。甚至说,如果B的代码写的出问题了,有可能一直不调用close。
重要掌握的状态:
CLOSE_WAIT:服务器搜狐到 FIN 之后,进入的状态,等待用户代码调用close,来发送 FIN。
TIME_WAIT:表示是客户端收到了FIN 之后进入了 TIME_WAIT,这个状态存在的一对主要就是为了处理最后一个ACK丢包问题。
在三次握手和四次挥手的过程中,同样可能会丢包,一旦丢包就会触发超时重传
1)第一个FIN丢了,A 迟迟收不到ACK,就会重传FIN
2)第一个ACK丢了,A迟迟收不到ACK,还会重传FIN
3)第二个FIN丢了,B 迟迟收不到ACK,还会重传FIN
4)第二个ACK丢了,B 迟迟收不到ACK,还会重传FIN
假设,如果A收到FIN之后,并返回ACK之后,连接就销毁,而不是进入TIME_WAIT状态,会发生什么?
此时一旦最后一个ACK丢了,就无法重传ACK了,因为连接已经销毁了。
TIME_WAIT即使进程已经退出了,TIME_WAIT状态仍然会存在(TCP 连接不会立即销毁)
TIME_WAIT会等待一定的时间,如果一定时间之内也没有重传的FIN过来,才真正销毁
如果服务器上出现大量的CLOSE_WAIT,这是啥情况?
这是代码出现的bug,close没有及时被调用到。
如果服务器上出现大量的TIME_WAIT,是啥情况?
这个也可能是代码bug,但是不能石锤,主动发起FIN的一方会进入TIME_WAIT,就需要排查服务器是否应该主动断开连接。
哪方先断开连接,哪方就会进入TIME_WAIT,进程退出之后,TIME_WAIT状态仍然存在,TCP连接仍然存在。
如果让服务器先退出,服务器这边就会进入到TIME_WAIT状态(原来的连接占据着端口),接下来如果服务器立即启动,新的进程又会尝试重新绑定这个端口。可能会存在端口绑定失败的情况。
4.滑动窗口
TCP不仅仅是为了保证可靠性,还要尽可能的提高传输效率。
其实可靠性和效率是矛盾的!TCP努力的在可靠性的前提之下,又做出了很多性能优化的手段。
在这个过程中,发送方要花很多时间来等,这个等待就浪费了大量的时间。
现在咱们是批量发送,一次发一波,一次等一波的ACK,把多组数据的ACK的等待时间给重叠起来了。
一次批量发的数据的长度,就成为“窗口大小”。
如果没有批量发送数据的长度限制(窗口无限大,完全不等ACK,就一直发),其实就没有可靠性可言。
如果窗口越大,整体的效率就越高,窗口越小,整体的效率就越低。
“滑动”的含义
当前窗口范围是1001 - 5000 ,也就意味着,发送方现在同时发送了 1001 - 2000,2001 - 3000,3001 - 4000,4001 - 5000,同时等待着四组数据的ACK。
假设,2001这个ACK先到发送方就会知道了,1001 - 2000这个数据已经被对方收到了,发送方也就不用继续等待这个数据了,接下来就立即再发一个5001 - 6000,仍然保证窗口大小是4份数据,保证当前同时等待4份数据的ACK
并不是把4份ACK都等到才发新的数据,而是随着收到ACK就随着往后发送。
如果在滑动窗口的场景中出现了丢包,怎么办?
这种情况下,没有关系,只要不是全部都丢了就好。
关键在于确认序列号的设定,后一个能包含前一个。
这种情况下,仍然需要进行重传,但是如何让发送方知道是数据报丢了呢?
因为1001丢包了,主机B会一直索要1001,确认序列号仍然是1001。
发送方这边,如果连续几次看到1001这个ACK,就知道了1001这个数据丢失了,接下来就会重传1001。
前面的2001 - 7000,这些数据已经到达了接收端了,只不过是在接收缓冲区里等待,当1001 - 2000这个数据到打的时候,B就知道了,7001之前的数据都到齐了,此时继续索要7001这个数据即可。
边栏推荐
- Uninstallation of mysql5.7.37 under CentOS7 [perfect solution]
- 15、网站统计数据
- Is interprofessional examination difficult?Low success rate of "going ashore"?Please accept this practical guide!
- print task sorting js od huawei
- SQL注入 Less47(报错注入) 和Less49(时间盲注)
- The difference between link and @import
- 11. Redis implements follow, unfollow, and follow and follower lists
- 【Android】Room —— SQLite的替代品
- JetPack组件Databinding
- 4. Sensitive word filtering (prefix tree)
猜你喜欢
工程(五)——小目标检测tph-yolov5
StringJoiner详解
Classic linked list OJ strong training problem - fast and slow double pointer efficient solution
Mysql 45讲学习笔记(二十三)MYSQL怎么保证数据不丢
The use of font compression artifact font-spider
共模电感的仿真应用来了,满满的干货送给大家
Installation, start and stop of redis7 under Linux
刚出道“一战成名”,安全、舒适一个不落
CorelDRAW2022精简亚太新增功能详细介绍
知识蒸馏7:知识蒸馏代码详解
随机推荐
IIR滤波器和FIR滤波器
Mathematical Ideas in AI
Unity3D Button mouse hover enter and mouse hover exit button events
Moxa NPort 设备缺陷可能使关键基础设施遭受破坏性攻击
execsnoop tool
CorelDRAW2022精简亚太新增功能详细介绍
【银行系列第一期】中国人民银行
8. Unified exception handling (controller notifies @ControllerAdvice global configuration class, @ExceptionHandler handles exceptions uniformly)
[C language foundation] Solve C language error: expected ';', ',' or ')' before '&' token
mycat的主从关系 垂直分库 水平分表 以及mycat分片联表查询的配置详解(mysql5.7系列)
Crypto Firms Offer Offer To Theft Hackers: Keep A Little, Give The Rest
Map.Entry理解和应用
【CV项目调试】CUDNN_CONVOLUTION_FWD_SPECIFY_WORKSPACE_LIMIT问题
Huawei od dice js
Multilingual settings of php website (IP address distinguishes domestic and foreign)
The application of AI in the whole process of medical imaging equipment
编译Hudi
什么是分布式锁?实现分布式锁的三种方式
10. Redis implements likes (Set) and obtains the total number of likes
关于 mysql8.0数据库中主键位id,使用replace插入id为0时,实际id插入后自增导致数据重复插入 的解决方法