【JavaEE】TCP网络原理

简介: 【JavaEE】TCP网络原理

1.TCP协议定义

TCP即Transmission Control Protocol,传输控制协议。TCP特点是有链接、面向字节流、全双工、可靠传输。

图解TCP协议段格式



各个字段的含义:


源/目的端口号:表示数据是从哪个进程来,到哪个进程去;

32位序号:指的是报文段序号,有时候我们会发多条数据,为了方便回答,进行编号;

32位确认号:这个确认号是针对序号设定的,为了防止回复串行;

4位TCP报头长度:表示该TCP头部有多少个32位bit(有多少个4字节);所以TCP头部最大长度是

15 * 4 = 60

6位标志位:

URG:紧急指针是否有效

ACK:确认号是否有效

PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走

RST:对方要求重新建立连接;我们把携带RST标识的称为复位报文段

SYN:请求建立连接;我们把携带SYN标识的称为同步报文段

FIN:通知对方,本端要关闭了,我们称携带FIN标识的为结束报文段

16位窗口大小:控制每次滑块的流量

16位校验和:发送端填充,CRC校验。接收端校验不通过,则认为数据有问题。此处的检验和不光包含TCP首部,也包含TCP数据部分。

16位紧急指针:标识哪部分数据是紧急数据;


2.TCP原理

TCP中可靠性核心机制有很多,在这里只对其中最重要的10个最重要的核心机制进行讲解。

2.1确认应答机制

TCP最核心的特点就是可靠性传输,确认应答机制就是保证可靠性传输的根本了,TCP在发送数据时会一起过去一个同步报文段(SYN),当接收方收到数据后,接收方会给发送方 发送一个应答报文(ACK)。如果发送方没有接收到应答报文大概率就是丢包了(下面说解决方案)。


1d78fb34c6244d9bb293e0403ca58a78.png


上方的例子是简单的考虑发一个消息回答一个消息,如果发送方发送了2条消息过来,第一条还没到,第二条已经到了(后发先至),那接收方应该如何对每个消息进行精确回答呢?这个就要提到序号/确认号了,他两个的作用就是让每条信息对应到每个回答的问题上去。看下方例子:我给女神发了两条信息,对这两条信息添加序号,当女神回复时,回复的信息就会携带确认号,这样就避免出现不确认女神先回答那个问题的尴尬场景。




在TCP中并没有一条消息、两条消息的概念,上方的例子只是帮助理解才用了,TCP中的数据传输是面向字节流的,TCP会针对每一个字节进行编码,从前向后,把每一个字节分别配一个编号。



2.2超时重传机制

在上方的确认应答中,我们提到了没有接收到应答报文的问题(丢包),超时重传机制就填了这个丢包的坑, 当发送方迟迟没有收到接收方的应答报文(ACK),那么接收方会再发送一边同步报文段(SYN),若过了一会还是没有接收到应答报文(ACK),一直尝试上方的操作,当超过一定的时长,就会停止发送;此时,TCP会重写建立连接,如果重置建立连接也失败了,就放弃网络通信了。


触发超时重传有两种方式:

1.数据直接丢了,接收方没收到,自然不会发ack

2.接收方收到数据了,返回的ack丢了


7f2c32231ffc42f2801c57aac71fe4ef.png


✨情况1很好理解,如果发送方的东西都没有到,那他就不会接收到接收方的回应,发送方感觉不对劲,就一直进行发送。

✨情况2,会有特殊的情况,当发送方发送数据时,接收方可能会接收到相同的数据报,不用担心,TCP帮我们给降重,不会出现一式两份的错误。


面试题:TCP如何实现可靠性传输的?

答:确认应答+超时重传(两个的具体实现)  

2.3连接管理

连接管理中包含建立连接(三次握手)与断开连接(四次挥手),如图是两个操作的步骤,下方会进行解读,这在提一下:建立连接一定是客服端发送的请求,断开连接可能是客服端提出的也可能是服务器提出的。



2.3.1建立连接(三次握手)

三次握手指通信双方,进行三次网络交互,相当于客户端和服务器,通过三次交互,建立了连接关系。



三次握手就是建立客户端和服务器的连接关系,举个易懂的例子:



A对B说你好吗?这就相当于发送了同步报文段(SYN);很好,你呢?相当于发送了应答报文(ACK)+同步报文段(SYN);me too。相当于发送了应答报文(ACK)。

如果你听别人说这是四次握手,其实这也是对的,我们常常将B方的ACK和SYN一起发送给A,如果将这两个部分拆开发送,那就是四次,如果合并到一起就是三次。

总结三次握手的作用:

1.三次握手相当于投石问路,验证客户端和服务器各自的发送能力和接收能力是否正常。

2.在握手的过程中,双方还会“协商”配置一些参数。

2.3.2断开连接(四次挥手)



四次挥手就是客户端发送一个结束报文,服务器收到后回应一下,然后服务器发送一个结束报文,客服端再回应一下,在服务器会有发送结束报文时,我们无法确定他是什么时候发的,他的时间不固定,因此我们一般将ACK和FIN两个报文分开发送。

2.4滑动窗口

TCP不仅要保证可靠性,还有保证效率,因此他来了---滑动窗口。



上方是我们刚才举得例子,此时A这边就要花费大量的时间等待ACK,这样会影响到传送的速率,降低TCP的传输效率。


1ce8ce867d164a50b60f97ac1e269e98.png


想要提高效率,就需要缩短等待得到时间,如何解决这个问题?那就是批量发送数据,一次发送多条数据,一次等待多个ACK,这一总的等待时间减少了,整体的效率就提高了,这个批量传输就是滑动窗口。我们把不需要等待,就直接发送的最大数据量称为“窗口大小”,上方图片中的窗口大小是4000。

他是如何滑动的呢?收到第一个ACK后,滑动窗口向后移动,继续发送第五个段的数据;依次类推,这个形式运行起来就像一个窗口在滑动,因此才取名为滑动窗口。



如果在这种情况下发送丢包了,如何重传?还是分两种情况

✨情况1:数据包已经抵达,ACK被丢了



这种情况下,部分ACK丢了并不要紧,因为可以通过后续的ACK进行确认;就拿上方的图片解释,在图中1001、3001、4001丢了,但6001传了过去,这一主机A可以通过判断6001传了过去来推测前方的也都传过去了。

✨情况2:数据包就直接丢了


673e271867054945a918626fb910c945.png


由于1001-2000这之间的数据丢了,所以接收方仍然在索要1001,接下来的几次ACK确认序号都是1001, 发送方就会感觉到异常,重写发送1001-2000这个数据了,发送成功后,接收方会返回7001这个确认序号,因为2001-7000之间的数据我们已经收到过了,因此,我们再要数据就要没有发送过来的数据了,看下图:



当1001这个数据重写传过来之后,缺少的拼图补全了,接下来就会找下一个缺少的部分,如果没有缺少的部分,就找到最大的报文向索要。

这种丢包重传的方式被称为“高速重发控制(快重传)”,只重传丢失的数据,可以视为是超时重传机制在滑动窗口下的变形; 如果当前传输数据密集, 按照滑动窗口的方式来传输, 此时按照快速重传来处理丢包; 如果当前传输数据稀疏, 就不再按照滑动窗口方式了传输了, 此时还是按照之前的超时重传处理丢包。

2.5流量控制

流量控制的特性:

接收端将自己可以接收的缓冲区大小放入 TCP 首部中的 "窗口大小" 字段,通过ACK端通知发送端;

窗口大小字段越大,说明网络的吞吐量越高;

接收端一旦发现自己的缓冲区快满了,就会将窗口大小设置成一个更小的值通知给发送端,如果发现满了。还是阻塞等待;

发送端接受到这个窗口之后,就会减慢自己的发送速度;

如果接收端缓冲区满了,就会将窗口置为0;这时发送方不再发送数据,但是需要定期发送一个窗口探测数据段,使接收端把窗口大小告诉发送端。


f6f7d5027ebf4257952c45bf532316d9.png


接收缓冲区就像一个水池,发送数据就是向里面灌水,当水多的时候,我们就让它流慢一点,如果满了,就停止流动。这个上方的接收缓存区大小为3000,传输三千后,接收缓冲区满了就会阻塞等待,发送方会过每一段时间发一个窗口探测报文,如果探测发现对方的接收缓冲区不是0了,就继续发送数据。


2.6拥塞控制

虽然TCP有了滑动窗口这个大杀器,能够高效可靠的发送大量的数据。但是如果在刚开始阶段就发送大量的数据,仍然可能引发问题。

因为网络上有很多的计算机,可能当前的网络状态就已经比较拥堵。在不清楚当前网络状态下,贸然发送大量的数据,是很有可能引起雪上加霜的。

TCP引入慢启动 机制,先发少量的数据,探探路,摸清当前的网络拥堵状态,再决定按照多大的速度传输数据;

如图这就是TCP的慢启动:



  1. 1.先给一个非常小的窗口,然后以指数的形式翻倍增长。
  2. 2.增长到基本稳定了再进行线性增长。
  3. 3.增长到网络拥塞,就循环进行上方的操作。

通过上方的实验发送,找到一个合适的发送速率,确认实际发送方的窗口的大小,

实际的窗口大小=min(拥塞串口,流量控制窗口)

2.7延迟应答

延迟应答是提高TCP传输效率的机制,通过这个延时,让接收方的应用程序趁机多消费点数据,此时反馈回来的窗口大小就会大一点,发送速率就可以快一点。

如果发送方发送了10条消息,接收方立即应答的话,就是10条消息未处理,如果我们对这些消息处理一部分(比如处理了5条)了,再去应答,我们就可以回答5条未处理,那么就是有5条的空闲区域,发送方就可以再次发送5条过来。

2.8捎带应答

在延迟应答的基础上,我们发现,很多情况下,客户端服务器在应用层也是 "一发一收" 的。意味着客户端给服务器说了 "How are you",服务器也会给客户端回一个 "Fine, thank you";那么这个时候ACK就可以搭顺风车,和服务器回应的 "Fine,thank you" 一起回给客户端。

2.9面向字节流(粘包问题)

因为TCP是面向字节流的,我们无法确定一条消息是从哪里开始,从哪里结束的,因此我们需要对读取数据采取一定的策略:

对于定长的包,保证每次都按固定大小读取即可;例如上面的Request结构,是固定大小的,那么就从缓冲区从头开始按sizeof(Request)依次读取即可;

对于变长的包,可以在包头的位置,约定一个包总长度的字段,从而就知道了包的结束位置;

对于变长的包,还可以在包和包之间使用明确的分隔符(应用层协议,是程序猿自己来定的,只要保证分隔符不和正文冲突即可);

2.10异常处理

⚒️1.进程关闭/进程崩溃

进程没有了,socket是文件,随之被关闭,虽然进程没有了,但是连接还在,仍然可以继续四次挥手结束。

⚒️2.主动关机(正常流程关机)

会关闭所以的进程,也会出发四次挥手,如果四次挥手完成了,就正常关闭;如果没有挥完,例如:对方发fin过来了,这边还没有来的及发送ack,就会发送重传,如果重传几次仍没了ack,就是尝试重置连接,如果连接不是,就释放连接。

⚒️3.主动掉电(拔电源的情况)

瞬间机器就关了,来不及进行任何挥手操作。

 1.接收方掉电

收不到ack=>超时重传=>重置连接=>释放连接

 2.发送方掉电

发送方断电,接收方不能立即知道,你这边是没有及时发送新的数据?还是直接噶了?


这就不得不提到TCP的一个机制“心跳包”这个机制就是保活机制,它的特点就是周期性,接收方会周期性的ping一下,发送方就就会发送一个pong来回复接收方,如果没有这个回复的话,怕就是挂了。


相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
4天前
|
安全 网络协议 网络安全
OWASP Top 10 网络安全10大漏洞——A01,源码+原理+手写框架
OWASP Top 10 网络安全10大漏洞——A01,源码+原理+手写框架
|
5天前
|
网络协议 网络性能优化
UDP与TCP:了解这两种网络协议的不同之处
UDP与TCP:了解这两种网络协议的不同之处
|
5天前
|
网络协议
TCP三次握手:实现网络通信的神秘仪式
TCP三次握手:实现网络通信的神秘仪式
|
6天前
|
关系型数据库 Java MySQL
【JavaEE】项目的部署-让网络上的人都能访问你的网站
【JavaEE】项目的部署-让网络上的人都能访问你的网站
4 0
|
6天前
|
机器学习/深度学习 存储 算法
卷积神经网络(CNN)的数学原理解析
卷积神经网络(CNN)的数学原理解析
35 1
卷积神经网络(CNN)的数学原理解析
|
6天前
|
网络协议 算法 网络性能优化
Qt TCP网络上位机的设计(通过网络编程与下位机结合)
Qt TCP网络上位机的设计(通过网络编程与下位机结合)
Qt TCP网络上位机的设计(通过网络编程与下位机结合)
|
6天前
|
网络协议 Unix 网络性能优化
网络编程 —— TCP 和 UDP 编程详解
网络编程 —— TCP 和 UDP 编程详解
网络编程 —— TCP 和 UDP 编程详解
|
6天前
|
网络协议 网络性能优化 网络架构
|
6天前
|
开发框架 网络协议 Java
【计算机网络】—— 网络应用通信基本原理
【计算机网络】—— 网络应用通信基本原理
12 0
|
6天前
|
JSON 网络协议 调度
LabVIEW开发TCP网络通讯程序4
LabVIEW开发TCP网络通讯程序4
11 0

热门文章

最新文章