知识点梳理:关于TCP与UDP你需要知道这些

2020/6/22 17:29:09

本文主要是介绍知识点梳理:关于TCP与UDP你需要知道这些,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

TCP&UDP

前言

一个秃了头的大师托梦给我说要想称为大神就要有一个完善的个人知识体系,我从梦中惊醒,打开笔记本开始了整理。。。

image-20200620165241171

运输层

谁在使用运输层

只有位于网络边缘部分的主机的协议栈才有运输层。它属于面向通信部分的最高层,同时也是用户功能中的最低层。

运输层的作用

运输层为相互通信的应用进程提供了逻辑通信。“逻辑通信”的意思是“好像是这样通信,但事实上并非真的这样通信”。因为分层的架构,运输层向高层用户屏蔽了下面网络核心的细节,它使应用进程看见的就是好像在两个运输层实体之间有一条端到端的逻辑通信信道。

不同的运输协议

这条逻辑通信信道对上层的表现却因运输层使用的不同协议而有很大的差别。

  • 当运输层采用面向连接TCP 协议时,尽管下面的网络是不可靠的(只提供尽最大努力服务),但这种逻辑通信信道就相当于一条全双工的可靠信道
  • 当运输层采用无连接UDP 协议时,这种逻辑通信信道是一条不可靠信道

TCP协议和UDP协议也是运输层的两个主要协议。

数据单元

两个对等运输实体在通信时传送的数据单位叫作运输协议数据单元 TPDU (Transport Protocol Data Unit)

  • TCP 传送的数据单位协议是 TCP 报文段(segment)
  • UDP 传送的数据单位协议是 UDP 报文或用户数据报

TCP与UDP的对比

image-20200615150103669

端口

为什么要有端口

因为主机上可能有多个进程同时进行通信,进程是动态创建和撤销的,需要一个能够确认找到进程的方法,如果使用进程标识符,但是不同的操作系统对于进程标识符的类型又不相同,所以引入端口概念。

端口用一个 16 位端口号进行标志,允许有65,535个不同的端口号。端口号只具有本地意义,即端口号只是为了标志本计算机应用层中的各进程。

由此可见,两个计算机中的进程要互相通信,不仅必须知道对方的端口号(为了找到对方计算机中的应用进程) ,而且还要知道对方的 IP 地址(为了找到对方的计算机)。

UDP协议

全称User Datagram Protocol,用户数据包协议

特点

  • UDP 是无连接的,发送数据之前不需要建立连接,因此减少了开销和发送数据之前的时延。
  • UDP 使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的连接状态表。
  • UDP 是面向报文的。UDP 对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。UDP 一次交付一个完整的报文。
  • UDP 没有拥塞控制,因此网络出现的拥塞不会使源主机的发送速率降低。这对某些实时应用是很重要的。很适合多媒体通信的要求。
  • UDP 支持一对一、一对多、多对一和多对多的交互通信。
  • UDP 的首部开销小,只有 8 个字节,比 TCP 的 20 个字节的首部要短。

面向报文

接收方 UDP 对 IP 层交上来的 UDP 用户数据报,在去除首部后就原封不动地交付上层的应用进程,一次交付一个完整的报文。所以应用程序需要选择一个合适的报文大小,否则都会对ip层的传输效率有影响。

image-20200615162611834

UDP报文格式

image-20200615163534336

分用

image-20200615164240648

校验

image-20200620163827936

TCP协议

特点

  • TCP 是面向连接的运输层协议,在无连接的、不可靠的 IP 网络服务基础之上提供可靠交付的服务
  • 每一条 TCP 连接只能有两个端点 (endpoint),每一条 TCP 连接只能是点对点的(一对一)
  • TCP 提供可靠交付的服务。
  • TCP 提供全双工通信
  • 面向字节流,TCP 把应用程序交下来的数据看成仅仅是一连串无结构的字节流

面向流

image-20200615170655024

  • TCP 连接是一条虚连接而不是一条真正的物理连接。
  • TCP 对应用进程一次把多长的报文发送到 TCP 的缓存中是不关心的。
  • TCP 根据对方给出的窗口值和当前网络拥塞的程度来决定一个报文段应包含多少个字节(UDP 发送的报文长度是应用进程给出的)。
  • TCP 可把太长的数据块划分短一些再传送。
  • TCP 也可等待积累有足够多的字节后再构成报文段发送出去。

socket

TCP 连接的端点不是主机,不是主机的IP 地址,不是应用进程,也不是运输层的协议端口。TCP 连接的端点叫做套接字 (socket) 或插口。端口号拼接到 (contatenated with) IP 地址即构成了套接字。

image-20200615171708273

image-20200615171751748

tcp报文格式

image-20200616220801993

一个 TCP 报文段分为首部和数据两部分,而 TCP 的全部功能都体现在它首部中各字段的作用。 TCP 报文段首部的前 20 个字节是固定的,后面有 4n 字节是根据需要而增加的选项 (n 是整数)。因此 TCP 首部的最小长度是 20 字节。

TCP如何保证可靠传输

确认和重传

停止等待协议

“停止等待”就是每发送完一个分组就停止发送,等待对方的确认。在收到确认后再发送下一个分组

image-20200615172833111

在接收方 B 会出现两种情况:

  1. B 接收 M1 时检测出了差错,就丢弃 M1,其他什么也不做(不通知 A 收到有差错的分组)。
  2. M1 在传输过程中丢失了,这时 B 当然什么都不知道,也什么都不做。

在这两种情况下,B 都不会发送任何信息。但A都必须重发分组,直到B正确接收为止,这样才能实现可靠通信

问题:A如何知道 B 是否正确收到了 M1 呢?

解决方法:超时重传,简单来说就是一段时间没收到确认就再发一次

A 为每一个已发送的分组都设置了一个超时计时器。 A 只要在超时计时器到期之前收到了相应的确认,就撤销该超时计时器,继续发送下一个分组 M2 。 若A在超时计时器规定时间内没有收到B的确认,就认为分组错误或丢失,就重发该分组。

问题:确认消息丢失等情况导致的B收到了多次M1请求,B是如何区分自己收到了多次重复的请求?

解决方法:编号

A为每一个发送的分组都进行编号。若B收到了编号相同的分组,则认为收到了重复分组,丢弃重复的分组,并回送确认。B为发送的确认也进行编号,指示该确认是对哪一个分组的确认。A根据确认及其编号,可以确定它是对哪一个分组的确认,避免重发发送。若为重复的确认,则将其丢弃。

image-20200616212519610

使用上述的确认和重传机制,我们就可以在不可靠的传输网络上实现可靠的通信。

ARQ

像上述的这种可靠传输协议常称为自动重传请求 ARQ (Automatic Repeat Request)。意思是重传的请求是自动进行的,接收方不需要请求发送方重传某个出错的分组。

连续ARQ

虽然停止等待协议可以实现可靠的传输,但是它有一个非常显著的缺点。就是信道利用率非常低

所谓信道利用率就是,分组发送的时间在一次传输中总时间中的占比(总时间包含发送时间,确认发送时间,以及确认接受时间)

image-20200616213319274

为了提高效率,提出流水线传输

流水线传输就是发送方可连续发送多个分组,不必每发完一个分组就停顿下来等待对方的确认。这样可使信道上一直有数据不间断地传送。

image-20200616213410308

此方法也被称为连续ARQ协议,其基本思想为:

  • 发送方一次可以发出多个分组
  • 使用滑动窗口协议控制发送方和接收方所能发送和接收的分组的数量和编号。
  • 每收到一个确认,发送方就把发送窗口向前滑动。
  • 接收方一般采用累积确认的方式。
  • 采用回退N(Go-Back-N)方法进行重传。

累计确认

接收方一般采用累积确认的方式。即不必对收到的分组逐个发送确认,而是对按序到达的最后一个分组发送确认,这样就表示:到这个分组为止的所有分组都已正确收到了。

image-20200616214200544

TCP 使用流水线传输和滑动窗口协议实现高效、可靠的传输

Go-back-N

所谓回退N,举例就是,发送方发送12345,接收方正确的收到了12,但是3迟迟没有收到,即使此时收到了45,也需要丢弃45,不确认,让发送方重发345。这样就是回退了n

image-20200616215423192

数据校验与分段

校验方法基本与UDP过程类似,不过多赘述,了解即可

MSS (Maximum Segment Size)是 TCP 报文段中的数据字段的最大长度。数据字段加上 TCP 首部才等于整个的 TCP 报文段。所以,MSS是“TCP 报文段长度减去 TCP 首部长度”。选择较小的 MSS 长度,网络的利用率就降低。若 TCP 报文段非常长,那么在 IP 层传输时就有可能要分解成多个短数据报片。在终点要把收到的各个短数据报片装配成原来的 TCP 报文段。当传输出错时还要进行重传。这些也都会使开销增大。

因此,MSS 应尽可能大些,只要在 IP 层传输时不需要再分片就行。

流量控制

概念

所谓流量控制就是让发送方不要发的过快,让接收方来得及接收。

滑动窗口机制

首先:TCP 连接的每一端都必须设有两个窗口——一个发送窗口和一个接收窗口。

因为是全双工通信,意味着双方都有可能发送与接收数据,所以都需要维护两个窗口

image-20200616214608168

原理其实很easy,以上图举例

发送端维护着一个大小为5的发送窗口,接收方维护着大小为3的窗口

发送方发送3和4,此时发送窗口缩小,一直到收到确认。

image-20200616214855416

接收方收到对应分组后会向前滑动,并返回确认

image-20200616214955853

收到确认后发送窗口向前滑动,并扩大

image-20200616215034593

流控举例

image-20200619112635122

死锁问题

image-20200619113122722

糊涂窗口综合征

往细了分其实还分发送方糊涂窗口综合征还有接收方糊涂窗口综合征

发送方糊涂窗口综合征

每次仅发送一个字节或很少几个字节的数据时,有效数据传输效率变得很低的现象。

Nagel算法
  1. 若发送应用进程把要发送的数据逐个字节地送到 TCP 的发送缓存,则发送方就把第一个数据字节先发送出去,把后面到达的数据字节都缓存起来。
  2. 当发送方收到对第一个数据字符的确认后,再把发送缓存中的所有数据组装成一个报文段发送出去,同时继续对随后到达的数据进行缓存。
  3. 只有在收到对前一个报文段的确认后才继续发送下一个报文段。
  4. 当到达的数据已达到发送窗口大小的一半或已达到报文段的最大长度时,就立即发送一个报文段。

image-20200619152014588

接收方糊涂窗口综合征

其实就是接收方消耗数据比较慢,一次性只接一个或者几个字节,导致发送方发了又满,如此往复

解决方法:让接收方等待一段时间,使得或者接收缓存已有足够空间容纳一个最长的报文段,或者等到接收缓存已有一半空闲的空间。只要出现这两种情况之一,接收方就发出确认报文,并向发送方通知当前的窗口大小。

拥塞控制

在某段时间,若对网络中某资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种现象称为拥塞 (congestion)。

TCP的流量控制方法

TCP 采用基于窗口的方法进行拥塞控制。TCP发送方维持一个拥塞窗口 cwnd (Congestion Window)。真正的发送窗口值 = Min (接收方窗口值,拥塞窗口值)

怎样算拥塞

  1. 重传定时器超时
  2. 收到三个重复的ACK

所以下面的算法是用来控制拥塞窗口大小变化的

慢开始

  • 目的:用来确定网络的负载能力或拥塞程度。
  • 算法的思路:由小到大逐渐增大拥塞窗口数值。
  • 两个变量:1、拥塞窗口 2、慢开始门限
  • 过程简述:简答来说,初始设定一个拥塞窗口大小和一个门限,每次收到一个新报文的ACK就让拥塞窗口大小翻倍,直到触及门限。
  • 当触及门限时由慢开始算法调整为拥塞避免算法

拥塞避免

  • 思路:让拥塞窗口 cwnd 缓慢地增大,避免出现拥塞。
  • 过程简述:每经过一个传输轮次,拥塞窗口 cwnd = cwnd + 1。

阻塞发生

无论在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(重传定时器超时)

  1. 门限变为max (cwnd/2,2)
  2. cwnd = 1
  3. 执行慢开始算法

目的:迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够时间把队列中积压的分组处理完毕。


快重传&快恢复

发送方只要一连收到三个重复确认,就知道接收方确实没有收到报文段,因而应当立即进行重传(即“快重传”),这样就不会出现超时,发送方也不就会误认为出现了网络拥塞。快重传并非取消重传计时器,而是在某些情况下可以更早地(更快地)重传丢失的报文段。

当发送端收到连续三个重复的确认时,由于发送方现在认为网络很可能没有发生拥塞,因此现在不执行慢开始算法,而是执行快恢复算法 FR (Fast Recovery) 算法:

  1. 慢开始门限 ssthresh = 当前拥塞窗口 cwnd / 2 ;
  2. 新拥塞窗口 cwnd = 慢开始门限 ssthresh ;
  3. 开始执行拥塞避免算法,使拥塞窗口缓慢地线性增大。

image-20200620162118982

参考学习:www.bilibili.com/video/BV1L4…

TCP如何建立连接

建立连接(三次握手)

image-20200620150950502

为什么握手

TCP 协议为了实现可靠传输, 通信双方需要判断自己已经发送的数据包是否都被接收方收到, 如果没收到, 就需要重发。 不握手不能知道对方是否收到。

为什么可以是三次握手、为什么不能是两次握手或者四次

两次过程:

1、可能会出现资源浪费的情况,比如A先发起一个tcp连接请求但是因为意外导致没有传输到B,A又发了一个连接请求,第二个请求顺利的到达了B,然后两次握手建立连接,传输数据,然后关闭,关闭完了之后第一次请求到达了B,B误以为A又发起了一个新的连接请求,并发送了确认,同时自己进入了连接建立状态,但是实际上A并没有发送,导致资源浪费

image-20200620154810822

2、B的初始序号得不到确认,举例当只有两次确认的情况下,A发起连接同时携带自己的初始序号,此时B发送确认同时携带对于A需要的确认,但是B的初始需要就没办法确认了!

image-20200620155221475

四次过程:没必要,完全可以简化成3次,B的确认和请求同步可以放在一次请求里面进行

image-20200620154636575

关闭连接(四次挥手)

image-20200620155616656

MSL

最长报文段寿命,是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃

为什么不直接关闭而是进入TIME_WAIT状态

1、A最后一次确认如果丢失了,会导致B重传,但是A已经关闭,这样会导致B反复重传且一直处于最后确认状态

为什么TIME_WAIT是2MSL

这2个MSL中的第一个MSL是为了等自己发出去的最后一个ACK从网络中消失,而第二MSL是为了等在对端收到ACK之前的一刹那可能重传的FIN报文从网络中消失。

如果TIME_WAIT状态保持时间不足够长,第一个连接就正常终止了。第二个拥有相同五元组的连接出现,而第一个连接的重复报文到达,干扰了第二个连接。TCP事先必须防止某个连接的重复报文在连接终止后出现,所以让TIME_WAIT状态保持时间足够长(2MSL),连接相应方向的上的TCP报文要么完全响应完毕,要么被丢弃。建立第二个连接的时候,不会混淆。

保活计时器

保活计时器 通常设置为2小时 。若服务器过了2小时还没有收到客户的信息,它就发送探测报文段。若发送了10个探测报文段(每一个相隔75秒)还没有响应,就假定客户出了故障,因而就终止该连接。 用来防止在TCP连接出现长时期的空闲。

参考

计算机网络(第7版)谢希仁 编著(文中很多图片来自此书的配套ppt,真的受益匪浅,🙏)

B站湖科大教书匠老师的关于计算机网络运输层的几个视频,在看其中几个知识点时纯文字的描述有些晦涩,我比较愚钝理解较慢,看了视频豁然开朗🙏

知乎上大神们的回答!!


整理不易,越整理越知道自己的不足,继续坚持✊ 冲啊!!! 冲TMD,希望能看到这篇的大家伙们也都有所收获,加油奥利给



这篇关于知识点梳理:关于TCP与UDP你需要知道这些的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程