[JavaEE] TCP协议
目录
一、TCP协议段格式
TCP全称为"传输控制协议(Transmission Control Protocol")。
源/目的端口号:标识数据是从哪个进程来,到那个进程去;
4位TCP报头长度:表示该TCP头部有多少个32位bit(有多少个4字节,单位是4字节)
6保留位:为后续的可拓展性留下的没被启用的空间
6标志位:
URG:紧急指针是否有效
ACK:确认号是否有效
PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走
RST:对方要求重新建立连接,RST标识的被称为复位报文段
SYN:请求建立连接;SYN标识的被称为同步报文段
FIN:通知对方,本端要关闭了,FIN标识的被称为结束报文段
16位校验和:发送端填充,通过CRC校验,如果接收端校验不通过,则认为数据有问题,包含TCP首部和数据部分。
16位紧急指针:标识那部分数据是紧急数据
二、TCP确保传输可靠的机制
2.1 确认应答
在接收方收到数据之后,就要给发送方返回一个“应答报文”(ack/acknowledge)。
在网络信息传输中,由于每个信息所通过的传输路径不相同,所以可能造成,后发的信息早于先发的信息到达接收端,我们把这个现象叫做“后发先至”。针对于这个现象,TCP中通过针对信息进行“编号”方法解决。
TCP面向字节流,所以编号的排序是按照字节来排,且字节之间是连续递增的,这种按照字节排序的机制,就叫做“TCP的序号”,在应答报文中,针对接受之前数据的排序的机制,就叫做“确认序号”。
丢包:数据传输的过程中,可能会发生bit翻转,接受方接受这个数据发现校验和对不上了,就会把这个数包丢弃。也可能是数据传输到某个节点,这个节点负载过高的时候,就会发生丢。
针对上方提到的丢包现象,TCP为了确保传输的可靠性,接收方会有一个“接受缓冲区”,接收方接收到数据,先进入到缓冲区里,后续再接收到数据,就会根据序号在缓冲区中排序,如果发现有重复的现象,缓冲区就会自动去掉重复的数据。
2.2 超时重传
超时重传,这里的超时指的并不是时间,而是动态变化的。第一次传的时候花费t1时间,如果长时间没有ack就会发送第二次,花费的时间t2>t1,每次重传的时候时间就会增加,如果重传多次之后都没有ack,这时TCP就会发送一个特殊的数据包“复位报文”,再次建立连接重新连接,使通信可以继续进行,如果复位报文没有得到回应,这时TCP就会单方面放弃连接。
2.3 连接管理
2.3.1 三次握手
在连接前,客户端会发送一个没有业务的数据包,也就不包含任何数据,只有TCP报头。在客户端发送syn同步请求之后,服务器接收之后也会发送一个ack+syn来回应客户端,客户端收到服务器发送的syn请求之后,会发送一个ack返回给服务器。
三次握手的意义:
投石问路,初步验证信息的链路是否通畅,是可靠传输的“前提条件”,确认双方各自的接受和发送能力正常。
这个过程也需要确定TCP序号开始的大小,这样做的意义就是为了避免,一个数据包走丢的过久,导致传输到服务器的时候已经不需要了。
协商参数,通信双⽅共同确认⼀些通信中的必备参数数值。
2.3.2 四次挥手
双方各自把对端的信息删除,简略过程如下图,这里面不同于“三次握手”需要发送四次,因为ack是由系统内核所发出的,而FIN是由程序经过逻辑代码发出的,所以需要分两次发送。
TCP的几个状态转化
1.LISTEN:服务器的状态,服务器好绑定端口,表示可以建立连接。
2.ESTABLISHED:客户端和服务器的状态,表示建立完结完毕(保存好对方信息)。
3.CLOSE_WAIT:被动断开连接的一方,也就是先收到FIN的一方(等待代码执行close方法)。如果服务器存在大量CLOSE_WAIT状态的TCP连接,说明调用close方法出现问题。
4.TIME_WAIT:客户端接收到服务器的ACK和FIN之后,按照时间来等待,达到一定状态之后释放连接,因为存在客服端发送ACK丢包的现象,所以需要等待一段时间。如果保存一段时间之后,没有收到重传FIN,说明ACK没有丢包,也就会释放连接。
TIME_WAIT存在的时间,成为2MSL,不同系统不一样,是可配置的。
2.4 滑动窗口
2.4.1 基础知识
刚才我们讨论了确认应答策略,对每⼀个发送的数据段,都要给⼀个ACK确认应答。收到ACK后再发送下 ⼀个数据段。这样做有⼀个⽐较⼤的缺点,就是性能较差,尤其是数据往返的时间较⻓的时候。
窗口大小:把“发送一次等待一个”改进为“发送一批等待一批”,批量发送数据,不需要等待的数据的量,成为“窗口大小”,批量发送的单位是字节。
如上图发送前四个段的时候,不需要等待任何ACK,直接发送;
收到第一个ACK后,滑动窗口向后移动一个单位,继续发送第五个段的数据;
操作系统为了维护这个滑动窗口,需要开辟发送缓冲区,来记录当前还有哪些数据没有应答,只有确认应答过的数据,才能从缓冲区删除;
窗口越大,网络的吞吐率就越高。
2.4.2 两种丢包情况
2.4.2.1 数据报已经抵达,ACK丢包
ACK丢包并不要紧,因为后面的ACK包括前面的,可以通过后面的ACK是否发送来进行确认。
2.4.2.2 数据包丢包
快速重传:上图中,快速识别哪个数据包丢包之后,并且针对性的重传,其他顺利到达的数据无需重传,这个过程被称为“快速重传”
2.5 流量控制
TCP⽀持根据接收端的处理能力,来决定发送端的发送速度。这个机制就叫做流量控制(Flow Control)。
接收端处理数据的速度是有限的。如果发送端发的太快,导致接收端的缓冲区被打满,这个时候如果发送端继续发送,就会造成丢包,继而引起丢包重传等等⼀系列连锁反应。窗口大小并不是越大越好,针对于确定窗口大小的合理大小,TCP内有流量控制机制。接收方有接收缓冲区,根据序号排序并且去重,并且向发送方反应缓冲区的剩余空间是否过小。
接受端将自己的可以接受的缓冲区大小放入TCP首部中的“窗口大小”字段,通过ACK端通知发送;
窗口大小字段越大,说明网络的吞吐量越高;
接收端一旦发现自己的缓冲区快满了,就会将窗口大小设置成一个更小的值通知给发送端;
发送端接收到这个窗口之后,就会减慢自己的发送速度;
如果接收端缓冲区满了,就会将窗口设置为0,这是发送方不再发送数据,但是需要定期发送一个窗口探测数据段,使接收端把窗口大小告诉发送端。
由于TCP首部中,只有一个16位窗口字段,我们所传输的最大上限是固定的,TCP为了解决这个问题,在首部选项中包含了一个窗口扩大因子M,实际窗口大小是 窗口字段的值左移M位;
2.6 拥塞控制
在接收端有流量控制的机制,可是一旦发送方开始就大量的发送数据,可能会造成路由器的阻塞,而导致频繁丢包的现象。为了解决发送方的问题,TCP引入了一个慢启动机制,先发送少量的数据,再决定按照多大的速度传输数据。
此处引入一个概念程为拥塞窗口,发送开始的时候,定义拥塞窗口大小为1,每次收到一个ACK应答,拥塞窗口增加1。每次发送数据包的时候,将拥塞窗口和接收端主机反馈的窗口大小 做比较,取较小的值作为实际发送的窗口。
像上面这样的拥塞窗口增长速度,是指数级别的,“慢启动”知识初始时慢,但是增长非常快。
为了不增长那么快,引入一个叫慢启动的阈值,当拥塞窗口超过这个阈值的时候,不再按照指数指数方式增长,而是按照线性方式增长。当TCP开始启动的时候,慢启动阈值等于窗口最大值,在每次超时重发的时候,慢启动阈值会变成原来的一半,同时拥塞窗口置为1.
2.7 延迟应答
如果直接接受数据的主机直接返回ACK的应答,这时候返回的窗口可能比较小,如果稍慢一下返回ACK应答,有可能经过这一小段时间之后,空间就变大了。当然,并不是一定空间会变大,也有可能由于发送发发送的数据量大于接收方处理的能力,就会造成延时应答之后空间变小。
数据多的时候:每隔N个包就应答一次;
数据少的时候:通过时间限制,超过最大延时时间就应答一次。
一定要记得,窗口越大,网络吞吐量就越大,传输效率就越高。我们的目标是在保证网络不拥塞的情况下尽量提高传输效率。
2.8 捎带应答
在延时应答的基础上,我们可以将两个不同时间发送的数据一起返回。比如在四次握手的情况下,由于ACK是由系统内核所发,一定快于由程序逻辑所发的FIN,所以我们可以在延时应答的基础上,让ACK和FIN一起返回。
2.9 面向字节流
粘包问题
•首先要明确,粘包问题中的“包”,是指应用层的数据包
•在TCP协议头中,没有同UDP一样的“报文长度”这样的字段,但是有一个序号这样的字段。
•站在传输层的角度,TCP是一个一个报文过来的,按照序号排好序放在缓冲区中。
•站在应用层的角度,看到的只是一串连续的字节数据,
•那么应用层看到了这一传字节数据,不知道如何分割,才是一个完整的应用层数据包
所以为了避免粘包问题,需要明确两个包之间的边界
•方案一:指定分隔符
•方案二:指定数据的长度
•方案三:可以在包头的位置,约定⼀个包总⻓度的字段,从⽽就知道了包的结束位置。
对于UDP协议来说不存在“粘包问题”,因为一个DatagramSocket就是一个完整的应用层数据报。
三、异常情况
3.1 进程终止
进程终止会释放文件描述符,仍然可以发送FIN,和正常关闭没有什么区别。
3.2 机器重启
和进程终止情况相同。
3.3 机器掉电/网线断开
发送方掉电:TCP自己也内置了一个保活定时器,接收端会发送一个探测报文“心跳包”,定期询问对方是否还在,如果对方不在,也会把链接释放。
接收方掉电:发送方会触发超时重传,一定次数之后还没有发送到,会单方面释放连接。
=========================================================================
如果对你有用的话,请给博主一个三联,博主会继续努力的ヾ(◍°∇°◍)ノ゙
原文地址:https://blog.csdn.net/Miraitowa_cheems/article/details/142310776
免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!