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

avatar
作者
筋斗云
阅读量:0

文章目录

前言

在这里插入图片描述

再上一篇文章中 介绍了关于网络编程中应用层的一些基本知识,
本文会着重讲解传输层中Tcp和Udp两种协议

一、端口号

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

端口号的范围划分

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

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

谈到端口号,就要说说与它捆绑使用的进程了。
端口号是有限的,那么是否可以重复利用呢?

  1. 一个进程是否能绑定多个端口号呢?
  2. 一个端口号是否能被多个进程所绑定呢?

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

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

到了具体的企业开发中,是这样使用的。
就拿游戏来说
打开游戏,此时游戏就是一个进程,这个进程提供了两个端口号,一个供玩家进入,一个共开发人员进入。

游戏玩家进入游戏,可以享受正常的对局,但是对于游戏内的参数设置以及充值系统不能更改。
而开发人员进入游戏,可以设置对应的游戏参数,调整地图,优化系统,更爱游戏内氪金点数。

二、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个标志位:
  1. URG(Urgent): 紧急指针是否有效
  2. ACK(Acknowledgment): 确认号是否有效。*
  3. PSH(Push): 提⽰接收端应⽤程序⽴刻从TCP缓冲区把数据读⾛
  4. RST(Reset): 对⽅要求重新建⽴连接; 我们把携带RST标识的称为复位报⽂段
  5. SYN(Synchronization): 请求建⽴连接; 我们把携带SYN标识的称为同步报⽂段。
  6. FIN(Finish): 通知对⽅, 本端要关闭了, 我们称携带FIN标识的为结束报⽂段
  • 16位检验和: 发送端填充, CRC校验. 接收端校验不通过, 则认为数据有问题. 此处的检验和不光包含
    TCP⾸部, 也包含TCP数据部分.
  • 16位紧急指针: 标识哪部分数据是紧急数据;
  • 选项: Optional(可选项),可以自定义的勾选某些功能

四、TCP的十个核心机制

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

1.确认应答机制

在这里插入图片描述
对于用于应答的数据,称为应答报文

在这里插入图片描述

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

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

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

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
在这里插入图片描述
可以缩减为两次握手吗?
不可以,服务器对于通信双方的接收能力和发送能力的验证没能完成。
那么四次交互不是更直观吗?
这是因为三次的效率比四次要高。
在数据的传输过程中,要经过层层的封装和分用,多一次而带来的消耗就会很大。

三次握手的意义

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

三次握手协商
TCP通信时使用的序号,就是通过三次握手协商出来的。
第一次连接和第二次连接,协商出来的起始序号,往往差别很大。

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

四次挥手

客户端和服务端都可以先发起FIN(结束报文)
这里我们假定客户端先发起。
在这里插入图片描述
和三次握手是不是有点相似,那为什么三次握手就可以合并两次操作,而四次挥手不可以呢?

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

  • 一般情况
    当收到FIN报文时,内核直接就返回ACK报文,而FIN报文是由应用程序来控制的(socket.close),不是同一时刻,所有不能合并。
    三次握手是因为SYN和ACK都是由内核控制的,所以可以合并。
  • 特殊情况
    TCP有一个延时应答机制,在回复ACK数据报时,不是立即回复,而是等待一段时间,这时ACK和FIN就可以合并成一个报文了。

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

  1. close未调用
  2. 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    - 没有任何连接状态; 

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

4.滑动窗口

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

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

在这里插入图片描述

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

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

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

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

    在这里插入图片描述
    如果发现丢包怎么办?

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

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

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

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

滑动窗口有什么意义呢?
TCP为了保证可靠性,牺牲了很多的效率,滑动窗口就是为了弥补效率的牺牲,而采取的一种办法。
但是即使采取了措施,效率还是没有UDP快。

5.流量控制

流量控制其实是滑动窗口的一个控制窗口大小的补充。
接收端处理数据的速度是有限的,如果发的太快。接收端还没来得处理,接收端的缓冲区就满了,可能就会发生丢包,引起丢包重传等一系列问题。

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

在这里插入图片描述

6.阻塞控制

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

数据在网络的传输中,会经过很多网络结点。传输的速度就会受到这些结点的限制。
为了探寻传输数据的的最高效率,引入了阻塞控制
工作流程如下

  • 最开始按照小的速度,小的窗口来发送数据
  • 如果没有丢包,就加大速度,增大窗口,继续发送
  • 增加到一定程度,出现了丢包现象,就立即减小速度,缩小窗口
  • 当没有丢包情况出现后,就继续加大速度,增大窗口
  • 上述操作持续进行,直到找到一个阈值。

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

注意
阻塞控制的窗口变化也是有相应的规律的。
在这里插入图片描述

  1. 慢开始: 先以小的窗口传输数据,主要是检测通信路径是否通畅。
  2. **扩大窗口①:**以指数的形式来扩大窗口。
  3. **扩大窗口②:**到达某个阈值,就开始线性扩大窗口
  4. 缩小窗口:
    ①:窗口直接缩小到0,再重复上述流程,
    ②:窗口缩小一半,然后线性的增长窗口。

7.延迟应答

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

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

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

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

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

8.捎带应答

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

例如在三次挥手中,就将ACK报文和SYN报文合并在一起了。
这样做的意义:
可以调高效率,减轻服务器的压力,因为一次数据的传输,需要经过层层的封装和分用,,将两次操作合并成一次,减少了很多工作量。

9.粘包问题

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

为什么会出现这样的情况?
因为TCP协议报头并没有像UDP协议一样报头中有着报文长度这样的属性字段,所以不能确定一个数据报是多长而进行分割
站在传输层的角度来说,TCP是一个一个报文来的,按照序号排放在缓冲区中.
站在应用层的角度来说,看到的只是一串连续的字节数据,
应用程序看到了这么一连串的字节数据,就不知道从哪个部分开始到哪个部分结束是一个完整的数据包。

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

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

10.异常情况

  1. 一个进程崩溃
    进程终⽌会释放⽂件描述符, 仍然可以发送FIN. 和正常关闭没有什么区别.
    操作系统内核都会回收释放对应PCB,可以释放文件描述符表,相当于close。也会正常的进行四次挥手,一定会完成四次挥手。
  2. 主机正常关机
    这时,操作系统先会强制结束所有的进程,正常的进行四次挥手,但不一定会完成四次挥手,但是不影响。因为当发送了FIN后没有接收到ACK或者接收到ACK后,A进程结束,此时B的FIN会重复传送几次,如果重传了几次还是没有收到A的ACK,那么B还是会把A的信息(IP地址,端口号等)删除,此时A已经关机了所以A中B的信息也删除了。
  3. 主机电源断开
    分两种情况来分析:
  • 当接收端的电源断开时
    发送端接下来发送的数据,都不会有ACK了
    那么就会触发超时重传,重传几次之后,就会发送复位报文RST,当复位报文也没有响应时,发送端就会删除接收端的信息。
  • 当发送端的电源断开时
    接收方会在一段时间没有收到来自发送方的数据时,会触发一个心跳包
    心跳包的特点:有周期,有心跳就说明进程没有关闭
    在接收方发送了几次心跳包后,没有收到回复,那么就会认为发送方进程已经结束,就会删除发送端的信息。
  1. 网络断开
    本质也就是第三种。

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

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!