计算机网络-003-TCP、UDP

七层协议

应用层(报文):包含用户应用程序和协议;
表示层(报文):主要解决用户信息的语法表示问题,如会话加密与数据压缩、语法表示与连接管理;
会话层(报文):会话链接的恢复与释放、对会话进行分段,同步等;
传输层(段):提供端到端之间可靠透明的传输。分段与重组、差错控制及流量控制,保证数据传输的完整性和正确性;
网络层(分组):路径的选择,网络连接的多路复用、差错的检测与恢复、排序与流量控制、服务选择;
数据链路层(帧):把不可靠信道变为可靠信道,将比特组织成帧,在链路上提供点到点的帧传输,差错检测、流量控制等;
物理层(比特流):提供物理通路,二进制数据比特流传输、定义机械、电气特性和接口等。

请添加图片描述

各层使用的哪个数据交换设备?

  • 网关:应用层、传输层(网关在传输层上以实现网络互连,是最复杂的网络互联设备,仅用于两个高层协议不同的网络互连。网关的结构和路由器相似,不同的是互连层,网关既可以用于广域网互连,也可以用于局域网互连)

  • 路由器:网络层 (路由选择、存储转发)

  • 交换机 :数据链路层、网络层(识别数据中的MAC地址信息,根据MAC地址进行转发,并将这些MAC地址与对应的端口记录在自己内部的一个地址表中)

  • 网桥: 数据链路层(将两个LAN连起来,根据MAC地址来转发帧)

  • 集线器:物理层(纯硬件设备,主要用来连接计算机等网络终端)

  • 中继器: 物理层(在比特级别对网络信号进行再生和重定向时,从而使得它们能够在网络上传输更长的距离)

    原文链接:https://blog.csdn.net/qq_42033567/article/details/107392894

TCP/UDP协议

请添加图片描述

TCP(传输控制协议):TCP是一种面向连接的、可靠的传输层协议;TCP协议建立在不可靠的网络层 IP 协议之上,IP协议并不能提供任何可靠性机制,TCP的可靠性完全由自己实现;TCP采用的最基本的可靠性技术是:确认与超时重传机制、流量控制机制

  • 超时重传是TCP协议保证数据可靠性的一个重要机制,其原理是在发送某一个数据以后就开启一个计时器,在一定时间内如果没有得到发送的数据报的ACK报文,那么就重新发送数据,直到发送成功为止。
  • 流量控制就是让发送速率不要过快,让接收方来得及接收。利用滑动窗口机制就可以实施流量控制

用户数据报协议(用户报文协议)UDP:UDP是一种无连接的、不可靠传输层协议;提供了有限的差错检验功能;目的是希望以最小的开销来达到网络环境中的进程通信目的;

UDP协议以其简单、传输快的优势,在越来越多场景下取代了TCP,如网页浏览、流媒体、实时游戏、物联网。

  1. 网速的提升给UDP稳定性提供可靠网络保障,UDP的丢包率低于5%,如果再使用应用层重传,能够完全确保传输的可靠性。
  2. 对比测试结果UDP性能优于TCP,为了提升浏览速度,Google基于TCP提出了SPDY协议以及HTTP/2。Google在Chrome上实验基于UDP的QUIC协议,传输速率减少到100ms以内。
  3. TCP设计过于冗余,速度难以进一步提升
    TCP为了实现网络通信的可靠性,使用了复杂的拥塞控制算法,建立了繁琐的握手过程以及重传策略。由于TCP内置在系统协议栈中,极难对其进行改进。
  4. UDP协议以其简单、传输快的优势,在越来越多场景下取代了TCP

TCP与UDP的不同:

  1. 是否需要建立连接UDP在传送数据之前不需要先建立连接;TCP则提供面向连接的服务;
  2. 是否需要给出确认。对方的传输层在收到UDP报文后,不需要给出任何确认,而 TCP需要给出确认报文,要提供可靠的、面向连接的传输服务。
  3. 虽然UDP不提供可靠交付,但在某些情况下UDP是一种最有效的工作方式;【UDP取代TCP】

和IP层的联系: IP层只负责把数据送到节点,而不能区分上面的不同应用,所以TCP和UDP协议在其基础上加入了端口的信息,每个端口标识的是一个节点上的一个应用。 除了增加端口信息,UPD协议基本就没有对IP层的数据进行任何的处理了。而TCP协议还加入了更加复杂的传输控制,比如滑动的数据发送窗口,以及接收确认和重发机制,以达到数据的可靠传送。不管应用层看到的是怎样一个稳定的TCP数据流,下面传送的都是一个个的IP数据包,需要由TCP协议来进行数据重组。

TCP和UDP区别详解

https://blog.csdn.net/wyplj2015/article/details/108779017

TCP的粘包和粘包

什么是粘包?

在学习粘包之前,先纠正一下读音,很多视频教程中将“粘”读作“nián”。经过调研,个人更倾向于读“zhān bāo”。

如果在百度百科上搜索“粘包”,对应的读音便是“zhān bāo”,语义解释为:网络技术术语。指TCP协议中,发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。

TCP是面向字节流的协议,就是没有界限的一串数据,本没有“包”的概念,“粘包”和“拆包”一说是为了有助于形象地理解这两种现象。

为什么UDP没有粘包?

粘包拆包问题在数据链路层、网络层以及传输层都有可能发生。日常的网络应用开发大都在传输层进行,由于UDP有消息保护边界,不会发生粘包拆包问题,因此粘包拆包问题只发生在TCP协议中。

粘包拆包发生场景

因为TCP是面向流,没有边界,而操作系统在发送TCP数据时,会通过缓冲区来进行优化,例如缓冲区为1024个字节大小。

如果一次请求发送的数据量比较小,没达到缓冲区大小,TCP则会将多个请求合并为同一个请求进行发送,这就形成了粘包问题。

如果一次请求发送的数据量比较大,超过了缓冲区大小,TCP就会将其拆分为多次发送,这就是拆包。

关于粘包和拆包可以参考下图的几种情况:

在这里插入图片描述

粘包/拆包

上图中演示了以下几种情况:

  • 正常的理想情况,两个包恰好满足TCP缓冲区的大小或达到TCP等待时长,分别发送两个包;
  • 粘包:两个包较小,间隔时间短,发生粘包,合并成一个包发送;
  • 拆包:一个包过大,超过缓存区大小,拆分成两个或多个包发送;
  • 拆包和粘包:Packet1过大,进行了拆包处理,而拆出去的一部分又与Packet2进行粘包处理。
常见的解决方案

对于粘包和拆包问题,常见的解决方案有四种:

  • 发送端将每个包都封装成固定的长度,比如100字节大小。如果不足100字节可通过补0或空等进行填充到指定长度;
  • 发送端在每个包的末尾使用固定的分隔符,例如\r\n。如果发生拆包需等待多个包发送过来之后再找到其中的\r\n进行合并;例如,FTP协议;
  • 将消息分为头部和消息体,头部中保存整个消息的长度,只有读取到足够长度的消息之后才算是读到了一个完整的消息;
  • 通过自定义协议进行粘包和拆包的处理。
Netty对粘包和拆包问题的处理

Netty对解决粘包和拆包的方案做了抽象,提供了一些解码器(Decoder)来解决粘包和拆包的问题。如:

  • LineBasedFrameDecoder:以行为单位进行数据包的解码;
  • DelimiterBasedFrameDecoder:以特殊的符号作为分隔来进行数据包的解码;
  • FixedLengthFrameDecoder:以固定长度进行数据包的解码;
  • LenghtFieldBasedFrameDecode:适用于消息头包含消息长度的协议(最常用);

基于Netty进行网络读写的程序,可以直接使用这些Decoder来完成数据包的解码。对于高并发、大流量的系统来说,每个数据包都不应该传输多余的数据(所以补齐的方式不可取),LenghtFieldBasedFrameDecode更适合这样的场景。

TCP协议标志位的意义

6个标志位:

  • URG 紧急指针,告诉接收TCP模块紧要指针域指着紧要数据
  • ACK 置1时表示确认号(1为合法,为0的时候表示数据段不包含确认信息,确认号被忽略。
  • PSH 置1时请求的数据段在接收方得到后就可直接送到应用程序,而不必等到缓冲区满时才传送。
  • RST 置1时重建连接。如果接收到RST位时候,通常发生了某些错误。
  • SYN 置1时用来发起一个连接。
  • FIN 置1时表示发端完成发送任务。用来释放连接,表明发送方已经没有数据发送了。

其中URG不能和PSH标志位同时使用。
URG为紧急数据标志,如果URG为1,表示本数据包中包含紧急数据。此时紧急数据指针表示的值有效,它表示在紧急数据之后的第一个字节的偏移值(即紧急数据的总长度)。
ACK为确认标志位。如果ACK为1,表示数据包中的确认号有效。
PSH位,表示强迫数据传输。
RST标志位用来复位一条连接。当RST=1时,表示出现严重错误,必须释放连接,然后再重新建立。
SYN标志位用来建立连接,如果SYN=1而ACK=0,表明它是一个连接请求;如果SYN=1且ACK=1,则表示同意建立一个连接。
FIN为1时,表示数据已经发送完毕,希望释放连接。

6个标志位:

不合法的标志位组合。
1、所有标志位都为0。
2、SYN和FIN同时被置1。
3、SYN和RST同时被置1。
4、FIN和RST同时被置1。
5、FIN位被置1,但ACK位没有被置1。
6、PSH位被置1,但ACK位没有被置1。
7、URG位被置1,但ACK位没有被置1。

TCP滑动窗口

TCP是通过什么机制保障可靠性的?

从四个方面进行回答,ACK确认机制、超时重传、滑动窗口以及流量控制,深入的话要求详细讲出流量控制的机制。

1、ACK确认机制

https://blog.csdn.net/qq_40459977/article/details/123076728

2、超时重传

3、TCP滑动窗口实现流量控制

很多人把流量控制和拥塞控制搞混,所以单独拎出来,考究细节

流量控制:如果发送者发送数据过快,接收者来不及接收,那么就会有分组丢失。流量控制策略就是控制发送者的发送速度,从而接收者来得及接收,达到不丢失分组的目的。构成TCP可靠性的可靠性。

下面的图讲解滑动窗口(也叫接受窗口rwnd)的细节

主机A向主机B发送数据,开始双方确定的窗口数量为400字节,这两个是串行条件。开始A发送了200字节,之后发生了分组丢失现象,B调整接受窗口大小为300字节。之后A又连续发送了300个字节。此时A已经不能发送数据,需要等待B的窗口信号。之后B调整窗口为100字节。接收到100字节数据后,调整窗口大小为0,表示暂时不想接受数据。总计B调整了三次窗口大小,进行了三次流量控制

假如,B向A发送了零个窗口的报文段后不久,B的接收缓存又有了一些存储空间。于是B向A发送了rwind = 400的报文段,而这个报文段在传送中丢失了。A一直等待收到B发送的非零窗口的通知,而B也一直等待A发送的数据。这样就死锁了。为了解决这种死锁状态,TCP为每个连接提供一个持续计时器。仅要TCP连接的一方收到对方的零窗口通知,就启动连续计时器,若持续计时器设置的时间终止,就发送一个零窗口探测报文段(仅携带1字节的数据) ,而对方就在确认这个探测报文段时指定了现在的窗口值。

TCP的拥塞控制

产生的原因

  • 注意单纯的增加网络资源无法解决问题。例如:把结点的存储空间扩大,更换更高速率的链路,提高结点处理机的运算速度,不仅不能解决问题,而且可能使网络性能更坏。原因:网络拥塞是许多因素引起的,单纯的解决一个可能会使上述情况得到一些缓解,但是会把拥塞转移到其他地方。

  • 扩大结点存储空间——>由于输出链路的容量和处理机的速度并未提高,增大排队等待时间,超时重传,浪费资源。更换更高速率的链路——>可能会缓解,,有可能造成各部分不匹配。

拥塞控制的作用

注意
拥塞控制与流量控制的区别

  • 拥塞控制是防止过多的数据注入到网络中,可以使网络中的路由器或链路不致过载,是一个全局性的过程。

  • 流量控制是点对点通信量的控制,是一个端到端的问题,主要就是抑制发送端发送数据的速率,以便接收端来得及接收。

拥塞的标志

  1. 重传计时器超时
  2. 接收到三个重复确认
拥塞控制的机制
慢开始与拥塞避免

慢开始

  • 1.慢开始不是指cwnd的增长速度慢(指数增长),而是指TCP开始发送设置cwnd=1。

  • 2.思路:不要一开始就发送大量的数据,先探测一下网络的拥塞程度,也就是说由小到大逐渐增加拥塞窗口的大小。这里用报文段的个数的拥塞窗口大小举例说明慢开始算法,实时拥塞窗口大小是以字节为单位的。如下图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cpmYkNAo-1650588930208)(/Users/hello/Desktop/面试/image/截屏2022-03-17 19.20.16.png)]

  • 3.为了防止cwnd增长过大引起网络拥塞,设置一个慢开始门限(ssthresh状态变量)
    当cnwd<ssthresh,使用慢开始算法
    当cnwd=ssthresh,既可使用慢开始算法,也可以使用拥塞避免算法
    当cnwd>ssthresh,使用拥塞避免算法

拥塞避免(按线性规律增长)

1.拥塞避免并非完全能够避免拥塞,是说在拥塞避免阶段将拥塞窗口控制为按线性规律增长,使网络比较不容易出现拥塞。

2.思路:让拥塞窗口cwnd缓慢地增大,即每经过一个往返时间RTT就把发送方的拥塞控制窗口加一。

无论是在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有收到确认,虽然没有收到确认可能是其他原因的分组丢失,但是因为无法判定,所以都当做拥塞来处理),就把慢开始门限设置为出现拥塞时的发送窗口大小的一半。然后把拥塞窗口设置为1,执行慢开始算法。

加法增大与乘法减小
乘法减小:无论是慢开始阶段还是拥塞避免,只要出现了网络拥塞(超时),就把慢开始门限值ssthresh减半
加法增大:执行拥塞避免算法后,拥塞窗口线性缓慢增大,防止网络过早出现拥塞

快重传与快恢复

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zGD9xlRQ-1650588930209)(/Users/hello/Desktop/面试/image/截屏2022-03-17 19.19.29.png)]

快重传

  • 1.快重传要求接收方在收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方)而不要等到自己发送数据时捎带确认。快重传算法规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期。

  • 2.由于不需要等待设置的重传计时器到期,能尽早重传未被确认的报文段,能提高整个网络的吞吐量。

快恢复(与快重传配合使用)

  • 1.采用快恢复算法时,慢开始只在TCP连接建立时和网络出现超时时才使用。
  • 2.当发送方连续收到三个重复确认时,就执行“乘法减小”算法,把ssthresh门限减半。但是接下去并不执行慢开始算法。
  • 3.考虑到如果网络出现拥塞的话就不会收到好几个重复的确认,所以发送方现在认为网络可能没有出现拥塞。所以此时不执行慢开始算法,而是将cwnd设置为ssthresh的大小,然后执行拥塞避免算法。

注意
发送方窗口的上限值=Min(接受窗口rwnd,拥塞窗口cwnd)
rwnd>cwnd 接收方的接收能力限制发送方窗口的最大值
rwnd<cwnd 网络的拥塞限制发送方窗口的最大值

面试题
TCP的拥塞控制机制

答:我们知道TCP通过一个定时器(timer)采样了RTT并计算RTO,但是,如果网络上的延时突然增加,那么,TCP对这个事做出的应对只有重传数据,然而重传会导致网络的负担更重,于是会导致更大的延迟以及更多的丢包,这就导致了恶性循环,最终形成“网络风暴” —— TCP的拥塞控制机制就是用于应对这种情况。
首先需要了解一个概念,为了在发送端调节所要发送的数据量,定义了一个“拥塞窗口”(Congestion Window),在发送数据时,将拥塞窗口的大小与接收端ack的窗口大小做比较,取较小者作为发送数据量的上限。
拥塞控制主要是四个算法:

  • 1.慢启动:意思是刚刚加入网络的连接,一点一点地提速,不要一上来就把路占满。
    连接建好的开始先初始化cwnd = 1,表明可以传一个MSS大小的数据。
    每当收到一个ACK,cwnd++; 呈线性上升
    每当过了一个RTT,cwnd = cwnd*2; 呈指数让升
    阈值ssthresh(slow start threshold),是一个上限,当cwnd >= ssthresh时,就会进入“拥塞避免算法”

  • 2.拥塞避免:当拥塞窗口 cwnd 达到一个阈值时,窗口大小不再呈指数上升,而是以线性上升,避免增长过快导致网络拥塞。
    每当收到一个ACK,cwnd = cwnd + 1/cwnd
    每当过了一个RTT,cwnd = cwnd + 1
    拥塞发生:当发生丢包进行数据包重传时,表示网络已经拥塞。分两种情况进行处理:
    等到RTO超时,重传数据包
    sshthresh = cwnd /2
    cwnd 重置为 1

  • 3.进入慢启动过程
    在收到3个duplicate ACK时就开启重传,而不用等到RTO超时
    sshthresh = cwnd = cwnd /2
    进入快速恢复算法——Fast Recovery

  • 4.快速恢复:至少收到了3个Duplicated Acks,说明网络也不那么糟糕,可以快速恢复。
    cwnd = sshthresh + 3 * MSS (3的意思是确认有3个数据包被收到了)
    重传Duplicated ACKs指定的数据包
    如果再收到 duplicated Acks,那么cwnd = cwnd +1
    如果收到了新的Ack,那么,cwnd = sshthresh ,然后就进入了拥塞避免的算法了。

    原文链接:https://blog.csdn.net/shuxnhs/article/details/80644531

三次握手和四次挥手

三次握手

请添加图片描述

为什么不能两次?

  • 为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤
  • 如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认

三次握手是为了双方都确认对方都能够知道对方的起始序号,并且确认对方都收到了,才开始通讯。

深入理解:先假设是两次吧。我们知道, TCP的连接过程中有一个超时重传算法(karn算法是比较典型的), 如果client发出SYN包后, 由于网络原因, 没有立即收到ACK/SYN包, 那么client会再次发起SYN包。如果第二次SYN包正常达到且与server端建立了TCP连接, server端维护了一个连接, 一次貌似OK, 但别忘了, 第一次那个SYN包可能就在此时达到server端了, 于是server端又要维护一个连接, 而这个连接是无效的, 可以认为是死连接。 而一个进程打开的socket是有限度的, 维护这些死连接非常耗费资源。所以, 二次握手, 服务端有较大隐患, 容易因为资源耗尽而崩溃

通过这样的三次握手,客户端与服务端建立起可靠的双工的连接,开始传送数据。为了保证服务端能收接受到客户端的信息并能做出正确的应答而进行前两次(第一次和第二次)握手,为了保证客户端能够接收到服务端的信息并能做出正确的应答而进行后两次(第二次和第三次)握手。

四次挥手

状态转化:A、B连接建立状态ESTABLISHED -> A终止等待1状态FIN-WAIT-1 -> B关闭等待状态2CLOSE-WAIT -> A终止等待2状态FIN-WAIT-2 -> B最后确认状态LAST-ACK -> A时间等待状态TIME-WAIT -> B、A关闭状态CLOSED

四次挥手过程
第一次挥手:A数据传输完毕需要断开连接,A的应用进程向其TCP发出连接释放报文段(FIN = 1,序号seq = u),并停止再发送数据,主动关闭TCP连接,进入FIN-WAIT-1状态,等待B的确认。

第二次挥手B收到连接释放报文段后即发出确认报文段(ACK=1,确认号ack=u+1,序号seq=v),B进入CLOSE-WAIT关闭等待状态,此时的TCP处于半关闭状态,A到B的连接释放。而A收到B的确认后,进入FIN-WAIT-2状态,等待B发出的连接释放报文段。

第三次挥手:当B数据传输完毕后,B发出连接释放报文段(FIN = 1,ACK = 1,序号seq = u+1,确认号ack=v+1),B进入LAST-ACK(最后确认)状态,等待A 的最后确认。

第四次挥手:A收到B的连接释放报文段后,对此发出确认报文段(ACK = 1,seq=v+1,ack=u+2),A进入TIME-WAIT(时间等待)状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,A才进入CLOSE状态。

  • 客户端发送报文:FIN=1,seq=a;
  • 服务器响应报文:ACK=1,seq=b,ack=a+1;
  • 服务器发送报文:FIN=1,ACK=1,seq=a+1,ack=b+1;
  • 客户端响应报文:ACK=1,seq=b+1,ack=a+2

请添加图片描述

为什么A在TIME-WAIT状态必须等待2MSL(最大报文生存时间)的时间?

1.保证A发送的最后一个ACK报文段能够到达B,保证A、B正常进入CLOSED状态

这个ACK报文段有可能丢失使得处于LAST-ACK状态的B收不到对已发送的FIN+ACK报文段的确认,B超时重传FIN+ACK报文段,A能2MSL时间内收到这个重传的FIN+ACK报文段,接着A重传一次确认,同时重启2MSL计数器,2MSL时间后A和B进入CLOSE状态,如果A在TIME-WAIT状态时接收到B的FIN+ACK报文段之后向B发出确认报文段,而不再确认B是否收到立即进入CLOSED状态,如若B并没有正常收到A 的确认报文段,则B无法正正常进入到CLOSED状态。

2.防止“已经失效的连接请求报文段”出现在本连接中

A在发送完最后一个ACK报文段并经过2MSL,会使本次连接持续时间内所有产生的报文段消失,保证在下一次新连接中不会出现旧连接遗留的请求报文段。

TIME_WAIT状态为什么是2MSL的时长?为什么不是等待其他时长?

MSL,Maximum Segment Lifetime,最大报文段生存时间。即任何TCP报文在网络中存在的最大时长,如果超过这个时间,这个TCP报文就会被丢弃。2MSL,即两个最大报文段生存时间。
TIME_WAIT状态为什么是2MSL的时长?因为客户端不知道服务端是否能收到ACK应答数据包,服务端如果没有收到ACK,会进行重传FIN,**考虑最坏的一种情况:**第四次挥手的ACK包的最大生存时长(MSL)+服务端重传的FIN包的最大生存时长(MSL)=2MSL

请添加图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值