首页云计算【网络协议】一文带你搞懂Tcp和Udp(万字详解)

【网络协议】一文带你搞懂Tcp和Udp(万字详解)

时间2024-07-27 12:38:55发布ongwu分类云计算浏览58

前言

再上一篇文章中 介绍了关于网络编程应用层的一些基本知识,

本文会着重讲解传输层中Tcp和Udp两种协议

一、端口

网络通信中,我们以“源IP”,“源端口号”,“目的IP”,“目的端口号”,“协议号”这样的一个五元组来标识一个通信。

端口号的范围划分

端口号的范围是 0~65535,但在这其中还被划分为知名端口普通端口

0~1024: 知名端口号,HTTP,FTP,SSH等一些广为使用的应用协议,他们的端口号是固定的。1024 - 65535: 操作系统动态分配的端⼝号. 客⼾端程序的端⼝号, 就是由操作系统从这个范围分配的.

谈到端口号,就要说说与它捆绑使用的进程了。

端口号是有限的,那么是否可以重复利用呢? 一个进程是否能绑定多个端口号呢?一个端口号是否能被多个进程所绑定呢?

回答一下

一个进程可以绑定多个端口 一个端口号不能被多个进程所绑定

我们把进程想象成房间,把端口号想象成进入房间的门,是不是就可以具象化的理解了。

到了具体的企业开发中,是这样使用的。

就拿游戏来说

打开游戏,此时游戏就是一个进程,这个进程提供了两个端口号,一个供玩家进入,一个共开发人员进入。

游戏玩家进入游戏,可以享受正常的对局,但是对于游戏内的参数设置以及充值系统不能更改。

开发人员进入游戏,可以设置对应的游戏参数,调整地图优化系统,更爱游戏内氪金点数。

二、UDP和TCP

TCP (Transmission Control Protocol) 和 UDP (User Datagram Protocol) 是两种不同的网络传输协议

2.1 UDP

UDP协议格式

端口号和目的端口,标明了这个数据报从哪里来,要到哪里去。

UDP长度:

UDP数据报能传输64KB大小的数据

UDP长度在整个UDP数据报中占2个字节,也就是16位,能表示的范围就是0~65535.单位是字节 1024*64=65536。虽然UDP数据报的报头还有8个字节,64KB和64KB-8在实际的开发中,是忽略不计的,只要要传输的数据接近于64KB时,就需要注意了。

UDP校验和:

使用CRC的方式来完成。大致就是通过固定的公式来对要传输数据进行计算得到一个结果,发送方和接收方对两个结果进行比较,如果相等就说明传输的数据没有问题。感兴趣的可以去网上搜一搜相关的介绍,这里不就展开介绍了。

在数字电路中,电平通常用两个状态来表示,分别是高电平和低电平。 高电平表示逻辑1,低电平表示逻辑0。也就是计算机内部的那一串串的二进制数据,当受到电磁波、电信号、光信号的干扰时,可能就会发送比特翻转,造成数据传输的错误。

2.2 UDP的特点

UDP传输的过程类似于寄信.

⽆连接:

知道对端的IP和端⼝号就直接进⾏传输, 不需要建⽴连接;

比特就业课不可靠:

没有确认机制, 没有重传机制; 如果因为⽹络故障该段⽆法发到对⽅, UDP协议层也不会给应

⽤层返回任何错误信息;⾯向数据报: 不能够灵活的控制读写数据的次数和数量;

UDP的主要用途 应用于对性能要求高,但是对可靠性要求不高的场景

三、TCP

TCP是一种面向连接的协议,它在传输数据之前会建立一条专用的通信连接。这意味着在数据传输过程中,两台计算机之间会有一条稳定的数据传输通道。因此,TCP可以保证数据传输的可靠性,但会带来一定的延迟

TCP协议格式

16位源端口号和16位目的端口号: 表⽰数据是从哪个进程来, 到哪个进程去;32位序号: 发送数据每个字节都有一个序号,这个在后续的TCP确认应答机制中会看到实例32位确认序号: 接收方会给出一个确认序号,这个在后续的TCP确认应答机制中会看到实例4位首部长度:

这个字段是表示TCP数据报的报头有多大。

4位能表示 0~15,它的单位是‘4个字节’,也就是能表示最大60个字节,也就是表示TCP数据报的报头最大可以是60个字节,在报头部分我们可清楚的看到字段所占据的比特位,只有选项数据是没有给出大小的。选项

包含在报头部分,也就说选项这一部分最多可以表达40个字节大小的数据

TCP数据报整个报长在协议中没有规定保留(6位): 这个部分是留白,里面没有任何东西,是设计师预留出的给未来可能出现的功能位置6个标志位: URG(Urgent): 紧急指针是否有效ACK(Acknowledgment): 确认号是否有效。*PSH(Push): 提⽰接收端应⽤程序⽴刻从TCP缓冲区把数据读⾛RST(Reset): 对⽅要求重新建⽴连接; 我们把携带RST标识的称为复位报⽂段SYN(Synchronization): 请求建⽴连接; 我们把携带SYN标识的称为同步报⽂段。FIN(Finish): 通知对⽅, 本端要关闭了, 我们称携带FIN标识的为结束报⽂段 16位检验和:

发送端填充, CRC校验. 接收端校验不通过, 则认为数据问题. 此处的检验和不光包含

TCP⾸部, 也包含TCP数据部分.16位紧急指针: 标识哪部分数据是紧急数据;选项: Optional(可选项),可以自定义的勾选某些功能

四、TCP的十个核心机制

TCP最核心的机制就是可靠传输 而实现可靠传输就时依靠确认应答机制来实现的,其中超时重传是对确认应答的重要补充。

1.确认应答机制

对于用于应答的数据,称为应答报文

对于序号的解释

TCP会将每个字节的数据都进行编号,即位序列号

例如:

发送端,发送一个TCP数据报,载荷中的字节TCP会对其进行编号,当接收端接收到数据报后,会获取到数据报中的序号,进行一系列的业务逻辑后,对发送端数据报的序号+1,作为确认序号,并将ACK的值设为1,返回给发送端。

返回的确认序号有两层含义

告诉发送端这个序列号之前的数据我已经全部接收了请发送端下次发送数据时,从这个序号列开始发送

2.超时重传

在传输过程中出现丢包这种情况,

主机A将数据发送给主机B后,等待主机B的确认应答

当一段时间后还没有收到主机B的确认应答消息,此时主机A就会重新发送。

主机A是如何判断是否收到确认应答的呢?

主机A是通过是否收到了“ACK“来判断是否收到了应答。

如果一段时间内没有收到ACK,那么就认为是发生了丢包,就会重新发送。

那么问题又来了,ACK有没有可能会丢失呢?

答案是 会

如上就发生了丢失ACK的现象。

此时,主机B就收到了两份相同的数据,这样的情况肯定是不能存在的,在你游戏充值界面,你充值了50元,而由于服务器卡顿,给你的账号增加了100快价值的游戏币,肯定游戏厂商不会允许这样的情况发生的。

TCP接收方这边会对接收的数据按照序列号

来进行去重。

在TCP重复传输\重复接收是无所谓的,但会保证在应用层不会读取到重复的数据

那么超时重传的时间间隔是多少呢?

这个时间不是一个固定值,是会随着重传次数的增加而变长,

当时间达到一定阈值,就会重置连接。触发一个”复位报文“来进行尝试重连

但是当网络出现严重的故障时,RST也无法触发重置

只能断开连接(通信双方清除对方的数据 例如端口IP地址等)

总结一下

通信是如何实现可靠传输的? 在发送方发送数据时,会对字节进行编号,这个编号连续自增,TCP报头中的序号只存储第一个字节的序号,接收方在接收到全部数据后,会按照接收到的序号+1生成确认序列,这里的确认序号有两个作用,一是说明这个序号之前的数据都已经收到,二是接下来应该发送从确认序号开始的数据,并将报头中的ACK标识符的bit位更改1,生成应答报文返回给发送方。

通信中丢包怎么办? TCP拥有超时重传这样的机制,当一段时间后,发送方没有接收到来自于接收端的应答报文时,会重新传输数据报。

这里的时间间隔怎么设置 每次的间隔时间会变长,当到达一定阈值后,就会尝试重置连接

重置连接细节

此时会将报头中的RST标志位的bit位改为1,来进行重置连接。

此时 发送方和接收方就会清除互相的信息(端口号、IP地址等)

通信中出现重复的数据怎么办? TCP拥有一个接收缓冲区(类似于带有优先级的阻塞队列),当数据到达时,就会进入缓冲区,当应用程序进行read时,就会将数据从缓冲区删除,那么TCP接收会在缓冲区按照序列号来对数据进行去重。

为什么会出现重复的数据 因为发送方无法分辨是数据丢了,还是ACK丢了,如果是ACK丢了,就会收到重复的数据

3.连接管理–三次握手 四次挥手

建立连接:三次握手

断开连接:四次挥手 握手:发送一个不含业务数据数据报,不起到任何业务的作用,只是建立连接。 三次握手

在上述过程中,服务端客户端各自给对方发送一个SYN,再各自给对方返回一个ACK,实际上是四次交互。

其中,中间的ACK和SYN可以合并成一个数据报(这里是由内核完成的,当收到客户端的ACK同步报文后,立即生成ACK和SYN,这两是同一时刻由内核控制完成的

ACK的bit为1,SYN的bit为1 可以缩减为两次握手吗?

不可以,服务器对于通信双方的接收能力和发送能力的验证没能完成。

那么四次交互不是更直观吗?

这是因为三次的效率比四次要高。

数据的传输过程中,要经过层层的封装和分用,多一次而带来的消耗就会很大。

三次握手的意义

数据传输前,先确保通信链路是否通畅通过三次握手,来确认通信双方的接收和发送功能都是正常的。还需要协商一些必要的参数。有些参数不是单方面可以确定的,需要双方商量来决定。

三次握手协商

TCP通信时使用的序号,就是通过三次握手协商出来的。

第一次连接和第二次连接,协商出来的起始序号,往往差别很大。 这是为了避免当一个数据报在网络中传输时,可能由于线路规划不明确,导致在网络中一直游转,当通信双方断开连接时生成新的连接时(上一个业务结束,执行下一个业务),此时这个数据报才送到接收端,这时接收端就会根据序号的差异(检查序号时候如果差异过大,就会将这个数据报直接丢弃掉),从而防止上一次业务的逻辑运行到这次的业务中。 四次挥手

客户端服务端都可以先发起FIN(结束报文)

这里我们假定客户端先发起。

和三次握手是不是有点相似,那为什么三次握手就可以合并两次操作,而四次挥手不可以呢?

四次挥手的FIN和ACK报文可以合并吗? 在特殊情况下是可以的,但一般来说是不可以的。

一般情况

当收到FIN报文时,内核直接就返回ACK报文,而FIN报文是由应用程序控制的(socket.close),不是同一时刻,所有不能合并

三次握手是因为SYN和ACK都是由内核控制的,所以可以合并特殊情况 TCP有一个延时应答机制,在回复ACK数据报时,不是立即回复,而是等待一段时间,这时ACK和FIN就可以合并成一个报文了。

服务器看到大量的CLOSE_WAIT,可能是什么原因?

close未调用close调用不及时

LISTEN - 侦听来自远方TCP端口的连接请求; SYN-SENT - 在发送连接请求后等待匹配的连接请求; SYN-RECEIVED - 在收到和发送一个连接请求后等待对连接请求的确认; ESTABLISHED - 代表一个打开的连接,数据可以传送给用户; FIN-WAIT-1 - 等待远程TCP的连接中断请求,或先前的连接中断请求的确认; FIN-WAIT-2 - 从远程TCP等待连接中断请求; CLOSE-WAIT - 等待从本地用户发来的连接中断请求; CLOSING - 等待远程TCP对连接中断的确认; LAST-ACK - 等待原来发向远程TCP的连接中断请求的确认; TIME-WAIT - 等待足够的时间以确保远程TCP接收到连接中断请求的确认; CLOSED - 没有任何连接状态; 1234567891011

为什么会有TIME_WAI?服务器客户端发送FIN后,客户端不能立即释放TCP连接(因为此时客户端还没有发送ACK给服务器服务器一段时间没收到ACK就会重传FIN,当服务器重传FIN后,客户端还要将ACK返回给服务器,需要服务器端口号等信息,所以不能立即释放),在一定时间段内,没有收到服务器重传的FIN,就说明ACK已经被服务器所接收。

4.滑动窗口

在日常的业务背景下,有时会处理大量请求,这时,如果再一条一条发送,一条一条接收的话,效率非常低下。此时就引出华东窗口这样的机制了。

没错,就是算法题中的那个滑动窗口。

窗口大小指的是无需得到ACK应答就能发送数据的最大值,图中的窗口大小是2500个字节(五个段)

当一个段接收到ACK后,窗口就会向后移动,然后发送第六个段的数据

操作系统内核开辟了发送缓冲区来记录当前有哪些数据还没有应答,应答了的数据就会从缓冲区中删除

窗口越大,传输的数据就越多,网络的吞吐率就越高。

如果发现丢包怎么办?

丢的是ACK包: 不影响,因为后续的应答数据报的确认序列会告诉进程,这个序列号之前的数据,都已经接收了。

丢的是TCP数据报: 有影响,

当其中的一个数据报丢失了(例如这个窗口是501~2001,其中501-1000的这个数据报丢失了),那么接收端就会一直向发送端发送同一个应答数据报(要求下一个传输的数据报是从501开始,因为接收端没有接收到501-1000的数据报)当发送端连续收到这样的同一个应答数据报,就会重新发送501-1000的数据报当接收端接收到了501-1000的这个数据报,那么就会继续执行,下次执行的就是正在运行的正常的业务的应答数据报。(因为在这个过程中,操作系统内核会有一个接收缓冲区,会将正常的数据报都放在这里面,等处理完异常的情况后,就会根据缓冲区里的数据来继续执行)。

如上这样的处理方式称为快速重传

滑动窗口有什么意义呢?

TCP为了保证可靠性,牺牲了很多的效率,滑动窗口就是为了弥补效率的牺牲,而采取的一种办法。

但是即使采取了措施,效率还是没有UDP快。

5.流量控制

流量控制其实是滑动窗口的一个控制窗口大小的补充。

接收端处理数据的速度是有限的,如果发的太快。接收端还没来得处理,接收端的缓冲区就满了,可能就会发生丢包,引起丢包重传等一系列问题

因此TCP⽀持根据接收端的处理能⼒, 来决定发送端的发送速度. 这个机制就叫做流量控制(FlowControl);

6.阻塞控制

流量控制一样,是为了辅助滑动窗口使用的。

数据网络的传输中,会经过很多网络结点。传输的速度就会受到这些结点的限制。

为了探寻传输数据的的最高效率,引入了阻塞控制 工作流程如下 最开始按照小的速度,小的窗口来发送数据如果没有丢包,就加大速度,增大窗口,继续发送增加到一定程度,出现了丢包现象,就立即减小速度,缩小窗口当没有丢包情况出现后,就继续加大速度,增大窗口上述操作持续进行,直到找到一个阈值。

流量控制的窗口和阻塞控制的窗口选择哪个呢?

谁小听谁的

注意

阻塞控制的窗口变化也是有相应的规律的。

慢开始: 先以小的窗口传输数据,主要是检测通信路径是否通畅。**扩大窗口①:**以指数的形式来扩大窗口。**扩大窗口②:**到达某个阈值,就开始线性扩大窗口缩小窗口:

①:窗口直接缩小到0,再重复上述流程,

②:窗口缩小一半,然后线性的增长窗口。

7.延迟应答

在接收方接收到数据后,并不立即返回ACK,而是隔一段时间再返回ACK,这样可以提高传输速率

窗口越大,网络的吞吐量就越大,也就是说网络传输的速度也就越快 当接收方接收到数据后,处理数据需要时间,而延迟应答的这一段时间正好就可以处理数据,处理完数据后,缓冲区的空闲窗口就会变大,从而由流量控制来进行响应给出反馈,从而使得传输速度变快

说到延迟应答,就又跟四次挥手联系在一起了,延迟应答这种机制就可以将四次挥手给合并成三次挥手哦,不过这只是特殊情况。一般的情况就还是四次挥手。

** 延迟应答的时间的规划**

按照一定的时间来应答,一般是200ms按照收到的数据报个数来应答,一般是两个包

8.捎带应答

捎带应答 就是将两个数据报的内容在满足业务逻辑的情况下,将几个数据合并在一起。

例如在三次挥手中,就将ACK报文和SYN报文合并在一起了。

这样做的意义:

可以调高效率,减轻服务器的压力,因为一次数据的传输,需要经过层层的封装和分用,,将两次操作合并成一次,减少了很多工作量。

9.粘包问题

首先我们要明确,粘包问题粘的是应用层的数据

为什么会出现这样的情况? 因为TCP协议报头并没有像UDP协议一样报头中有着报文长度

这样的属性字段,所以不能确定一个数据报是多长而进行分割

站在传输层的角度来说,TCP是一个一个报文来的,按照序号排放在缓冲区中.

站在应用层的角度来说,看到的只是一串连续的字节数据

应用程序看到了这么一连串的字节数据,就不知道从哪个部分开始到哪个部分结束是一个完整的数据包。

说了这么多,那么该如何让避免呢?

使用分割符: 定义任意字符,来作为分隔符。例如用空格作为分割符来将包与直接分割开。约定包的长度: 在发送数据包之前,也将这个数据包的长度一同发送过去,从而就知道了包的结束位置

10.异常情况

一个进程崩溃

进程终⽌会释放⽂件描述符, 仍然可以发送FIN. 和正常关闭没有什么区别.

操作系统内核都会回收释放对应PCB,可以释放文件描述符表,相当于close。也会正常的进行四次挥手,一定会完成四次挥手。主机正常关机

这时,操作系统先会强制结束所有的进程,正常的进行四次挥手,但不一定会完成四次挥手,但是不影响。因为当发送了FIN后没有接收到ACK或者接收到ACK后,A进程结束,此时B的FIN会重复传送几次,如果重传了几次还是没有收到A的ACK,那么B还是会把A的信息(IP地址端口号等)删除,此时A已经关机了所以A中B的信息也删除了。主机电源断开

分两种情况来分析 当接收端的电源断开时

发送端接下来发送的数据,都不会有ACK了

那么就会触发超时重传,重传几次之后,就会发送复位报文RST,当复位报文也没有响应时,发送端就会删除接收端的信息。当发送端的电源断开时 接收方会在一段时间没有收到来自发送方的数据时,会触发一个心跳包

心跳包的特点:有周期,有心跳就说明进程没有关闭

在接收方发送了几次心跳包后,没有收到回复,那么就会认为发送方进程已经结束,就会删除发送端的信息。 网络断开

本质也就是第三种。

以上就是本文所有内容,如果对你有帮助的话,点赞收藏支持一下吧!💞💞💞

Ongwu博客 版权声明:以上内容未经允许不得转载!授权事宜或对内容有异议或投诉,请联系站长,将尽快回复您,谢谢合作!

展开全文READ MORE
Autodesk AutoCAD(CAD绘图软件) v2022.1.4 中文破解版 Jenkins使用pipline部署JAVA项目到远程服务器_pipeline 推送jar到其他服务器(1)

游客 回复需填写必要信息