[计算机网络] TCP和UDP总结及常见面试题

原文链接:https://blog.csdn.net/zhang6223284/article/details/81414149
本文仅作为个人整理笔记,供个人学习,自用不商用

知识点梳理总结部分

1 TCP和UDP区别

  • TCP是面向连接的,UDP是面向无连接的
  • TCP是可靠的,UDP不是可靠的
    (也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付)
  • TCP是面向字节流的,UDP是面向报文的
  • TCP只支持点对点通信,UDP支持一对一,一对多,多对一,多对多的通信模式
  • TCP首部开销(20字节)比UDP的首部开销(8个字节)要大
  • TCP保证数据正确性,UDP可能丢包
  • TCP保证数据顺序,UDP不保证

2 UDP

TCP 和 UDP 是传输层的两个协议

我们来看一下 UDP 的包头
在这里插入图片描述
由上图可以看出,UDP 除了端口号,基本啥都没有了。如果没有这两个端口号,数据就不知道该发给哪个应用。

所以 UDP 就像一个小孩子,特别简单,有如下三个特点

  • UDP 的特点
  • 沟通简单,不需要大量的数据结构,处理逻辑和包头字段
  • 轻信他人。它不会建立连接,但是会监听这个地方,谁都可以传给它数据,它也可以传给任何人数据,甚至可以同时传给多个人数据。
  • 愣头青,做事不懂变通。不会根据网络的情况进行拥塞控制,无论是否丢包,它该怎么发还是怎么发

因为 UDP 是"小孩子",所以处理的是一些没那么难的项目,并且就算失败的也能接收。基于这些特点的话,UDP 可以使用在如下场景中

UDP 的主要应用场景

  • 需要资源少,网络情况稳定的内网,或者对于丢包不敏感的应用,比如 DHCP 就是基于 UDP 协议的。
  • 不需要一对一沟通,建立连接,而是可以广播的应用。因为它不面向连接,所以可以做到一对多,承担广播或者多播的协议。
  • 需要处理速度快,可以容忍丢包,但是即使网络拥塞,也毫不退缩,一往无前的时候

基于 UDP 的几个例子

  • 直播。直播对实时性的要求比较高,宁可丢包,也不要卡顿的,所以很多直播应用都基于 UDP 实现了自己的视频传输协议
  • 实时游戏。游戏的特点也是实时性比较高,在这种情况下,采用自定义的可靠的 UDP 协议,自定义重传策略,能够把产生的延迟降到最低,减少网络问题对游戏造成的影响
  • 物联网。一方面,物联网领域中断资源少,很可能知识个很小的嵌入式系统,而维护 TCP 协议的代价太大了;另一方面,物联网对实时性的要求也特别高。比如 Google 旗下的 Nest 简历 Thread Group,推出了物联网通信协议 Thread,就是基于 UDP 协议的
    在这里插入图片描述

3 TCP

首先是 TCP 的包头格式

在这里插入图片描述

TCP 的包头有哪些内容,分别有什么用

  • 首先,源端口和目标端口是不可少的。
  • 接下来是包的序号。主要是为了解决乱序问题。不编好号怎么知道哪个先来,哪个后到
  • 确认序号。发出去的包应该有确认,这样能知道对方是否收到,如果没收到就应该重新发送,这个解决的是不丢包的问题
  • 状态位。SYN 是发起一个链接,ACK 是回复,RST 是重新连接,FIN 是结束连接。因为 TCP 是面向连接的,因此需要双方维护连接的状态,这些状态位的包会引起双方的状态变更
  • 窗口大小,TCP 要做流量控制,需要通信双方各声明一个窗口,标识自己当前的处理能力。

通过对 TCP 头的解析,我们知道要掌握 TCP 协议,应该重点关注以下问题:

  • 顺序问题
  • 丢包问题
  • 连接维护
  • 流量控制
  • 拥塞控制

4 TCP 的三次握手

所有的问题,首先都要建立连接,所以首先是连接维护的问题

TCP 的建立连接称为三次握手,可以简单理解为下面这种情况:

A:您好,我是 A
B:您好 A,我是 B
A:您好 B

至于为什么是三次握手,总结的话就是通信双方全都有来有回

对于 A 来说它发出请求,并收到了 B 的响应,对于 B 来说它响应了 A 的请求,并且也接收到了响应。

TCP 的三次握手除了建立连接外,主要还是为了沟通 TCP 包的序号问题。

5 TCP 四次挥手

说完建立连接,再说下断开连接,也被称为四次挥手,可以简单理解如下

A:B 啊,我不想玩了
B:哦,你不想玩了啊,我知道了
这个时候,只是 A 不想玩了,即不再发送数据,但是 B 可能还有未发送完的数据,所以需要等待 B 也主动关闭。
B:A 啊,好吧,我也不玩了,拜拜
A:好的,拜拜

这样整个连接就关闭了,当然上面只是正常的状态,也有些非正常的状态(比如 A 说完不玩了,直接跑路,B 发起的结束得不到 A 的回答,不知道该怎么办或则 B 直接跑路 A 不知道该怎么办)

6 累计确认

TCP如何实现可靠传输?

首先为了保证时序性,每个包都有一个ID。在建立连接的时候会商定起始ID是什么,然后按照ID一个个发送,为了保证不丢包,需要对发送的包都要进行应答,当然,这个应答不是一个一个来的,而是会应答某个之前的ID,表示都收到了,这种模式称为累计应答或累计确认。

为了记录所有发送的包和接收的包,TCP需要发送端和接收段分别缓存这些记录,
发送端的缓存里是按照包的ID一个个排序,根据处理的情况分为四个部分:

  • (1)发送并且确认的
  • (2)发送尚未确认的
  • (3)没有发送等待发送的
  • (4)没有发送并且暂时不会发送的
    这里的第三部分和第四部分就属于流量控制的内容

在TCP里,接收端会给发送端报一个窗口大小,叫Advertised window。这个窗口应该等于上面的第一部分加第二部分,超过这个窗口,接收端就接收不过来了,就不能发送了
于是,发送端要保持下面的数据结构
在这里插入图片描述
对于接收端,它的里面的内容要简单一些

  • (1)接收并且确认过的
  • (2)还没接收,但是马上 就能接收的
  • (3)还没接收,但也无法接收的

接收端对应的数据结构:
在这里插入图片描述

7 顺序问题和丢包问题

结合上面的图看,在发送端,1、2、3 已发送并确认;4、5、6、7、8、9 都是发送了还没确认;10、11、12 是还没发出的;13、14、15 是接收方没有空间,不准备发的。

在接收端来看,1、2、3、4、5 是已经完成 ACK 但是还没读取的;6、7 是等待接收的;8、9 是已经接收还没有 ACK 的。

发送端和接收端当前的状态如下:

  • 1、2、3 没有问题,双方达成了一致
  • 4、5 接收方说 ACK 了,但是发送方还没收到
  • 6、7、8、9 肯定都发了,但是 8、9 已经到了,6、7 没到,出现了乱序,缓存着但是没办法 ACK。
    根据这个例子可以知道顺序问题和丢包问题都有可能存在,所以我们先来看确认与重传机制。
假设 4 的确认收到了,5 的 ACK 丢了,6、7 的数据包丢了,该怎么办?

一种方法是超时重试,即对每一个发送了但是没有ACK的包设定一个计时器,超过了一定的时间就重新尝试。这个时间必须大于往返时间,但也不宜过长,否则超时时间变长,访问就变慢了。

如果过一段时间,5、6、7都超时了就会重新发送。接收方发现5原来接收过,于是丢弃5;6收到了,发送ACK,要求下一个是7,7不幸又丢了。当7再次超时的时候,TCP的策略是,超时间间隔加倍。 每当遇到一次超时重传的时候,都会将下一次超时间隔设置为之前的两倍。

超时重传的机制使超时周期可能相对较长,是否有更快的方式呢?

有一个快速重传的机制, 即当接收方收到一个序号大于期望的报文段时,就检测到了数据流之间的间隔,于是发送 三个冗余的ACK,客户端接收到之后,知道数据报丢失,于是重传丢失的报文段。
例如,接收方发现6,8,9都接收了,但是7没来,于是发送三个6的ACK,要求下一个是7。客户端接收到3个,就会发现7的确又丢了,不等超时,马上重发。

8 拥塞控制的问题

拥塞控制也是通过窗口的大小来控制的,但是检测网络满不满是个挺难的事情,所以TCP发送包经常被比喻成往水管里灌水,所以拥塞控制就是在不堵塞,不丢包的情况下尽可能的发挥带宽。

水管有粗细,网络有带宽,即每秒钟能发送多少数据;水管有长度,端到端有时延。
理想情况下,水管里面的水 = 水管粗细 * 水管长度,
对于网络上,通道的容量 = 带宽 * 往返时延。

如果我们设置发送窗口,使得发送但未确认的包为通道的容量,就能撑满整个管道。
在这里插入图片描述
如图所示,假设往返时间为 8 秒,去 4 秒,回 4 秒,每秒发送一个包,已经过去了 8 秒,则 8 个包都发出去了,其中前四个已经到达接收端,但是 ACK 还没返回,不能算发送成功,5-8 后四个包还在路上,还没被接收,这个时候,管道正好撑满,在发送端,已发送未确认的 8 个包,正好等于带宽,也即每秒发送一个包,也即每秒发送一个包,乘以来回时间 8 秒。

如果在这个基础上调大窗口,使得单位时间可以发送更多的包,那么会出现接收端处理不过来,多出来的包就会被丢弃,这个时候,我们可以增加一个缓存,但是缓存里面的包4秒内肯定达不到接收端了,它的缺点会增加时延,如果时延达到一定程度就会超时重传

TCP拥塞控制主要用来避免两种情况,包丢失和超时重传,一旦出现了这些现象说明发送的太快了,要慢一点。
具体的方法就是发送端慢启动, 比如倒水,刚开始倒的很慢,渐渐变快。然后设定一个阈值,当超过这个值的时候就要慢下来
慢下来还是在增长,这时候就可能水满则溢,出现拥塞,需要降低倒水的速度,等水慢慢渗下去。

拥塞的一种表现是丢包,需要超时重传,这个时候,采用快速重传算法,将当前速度变为一般,所以速度还是在比较高的值,也没有一夜回到解放前。

面试问题

9 面试问题

TCP和UDP的区别
  • TCP是面向连接的,UDP是面向无连接的
  • TCP是可靠的,UDP不是可靠的
    (也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付)
  • TCP是面向字节流的,UDP是面向报文的
  • TCP只支持点对点通信,UDP支持一对一,一对多,多对一,多对多的通信模式
  • TCP首部开销(20字节)比UDP的首部开销(8个字节)要大
  • TCP保证数据正确性,UDP可能丢包
  • TCP保证数据顺序,UDP不保证
什么是面向连接,什么是面向无连接

在互通之前,面向连接的协议会先建立连接,如 TCP 有三次握手,而 UDP 不会

  • **面向连接:**是指通信百双方在通信时,要事先建立一条通信线路,其有三个过程:建立连接、使用连接和释放连接。电话系统度是一个面向连接的模式,拨号、通知话、挂机;TCP协议就是一种面向连接的协议。
  • **面向无连接:**是指通信双方不需要事先建立一条通信线路道,而是把每个带有目的地址的包(报文分组)送到线路上,由系统自主选定路线进行传输。邮专政系统是一个无连接的模式,天罗地网式的选择路线,天女散属花式的传播形式;IP、UDP协议就是一种无连接协议。
TCP为什么是可靠连接
  • 通过TCP连接传输的数据无差错,不丢失,不重复,且按顺序到达
  • TCP报文头里面的序号能使TCP的数据按序到达
  • 报文头里面的确认序号能保证不丢包,累计确认及超时重传机制
  • TCP拥有流量控制及拥塞控制的机制
TCP协议如何来保证传输的可靠性

TCP提供一种面向连接的、可靠的字节流服务,
其中,面向连接意味着两个使用TCP的应用(通常是一个客户一个服务器)在彼此交换数据之前先见一个一个TCP连接。
在一个TCP连接中,仅有两方进行彼此通信,字节流服务意味着两个应用程序通过TCP链接交换8bit字节构成的字节流,TCP不在字节流中插入记录标识符。
对于可靠性,TCP通过以下方式进行保证:

  • **数据包校验:**目的是检测数据在传输过程中的任何变化,若检测出包有错,则丢弃褒文段并且不给出响应,这时TCP发送数据端超时后会重发数据
  • **对失序数据包重新排序:**既然TCP报文段作为IP数据报来传输,而IP数据报的到达可能会失序,因此TCP报文段的到达也可能会失序。TCP将对失序数据进行重排序,然后才交给应用层。
  • **丢弃重复数据:**对于重复数据,能够丢弃重复数据
  • 应答机制: 当TCP收到发自TCP连接另一端的数据,它将发送一个确认。这个确认不是立即发送,通常将推迟几分之一秒
  • 超时重发: 当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段
  • 流量控制 TCP连接的每一方都有固定大小的缓冲空间。TCP的接收端只允许另一端发送接收端缓冲区所能接纳的数据,这可以防止较快主机致使较慢主机的缓冲区溢出,这就是流量控制。TCP使用的流量控制协议是可变大小的滑动窗口协议。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章