计算机网络:传输层

IMG_2742(20210717-194249)

[!note]
MSS(TCP最大报文段长度):MSS=TCP报文段长度-TCP首部长度
MTU:maximum transmission unit,最大传输单元,由硬件规定,如以太网的MTU为1500字节。
MSS:maximum segment size,最大分节大小,为TCP数据包每次传输的最大数据分段大小,一般由发送端向对端TCP通知对端在每个分节中能发送的最大TCP数据。MSS值为MTU值减去IPv4 Header(20 Byte)和TCP header(20 Byte)得到

image.png

1 传输层

首部和数据差错检验,MSS(TCP最大报文段长度)

  • TCP(Transmission Control Protocol,传输控制协议 ):提供 面向连接 的,可靠 的数据传输服务。

  • UDP(User Datagram Protocol,用户数据协议):提供 无连接 的,尽最大努力 的数据传输服务(不保证数据传输的可靠性),简单高效。

1.1 滑动窗口

image.png

  • 基序号(base):最早未确认分组的序号

  • 下一个序号:下一个待发送分组序号

  • N:窗口长度

滑动窗口是一种流量控制机制,窗口是一个缓冲区,允许发送方在未收到确认的情况下发送数据。窗口的大小定义了发送方可以发送但还未被确认的数据段的最大数量。

  • 建立连接时的窗口大小协商:在TCP三次握手建立连接的过程中,双方会交换窗口大小的信息,以确定初始的窗口大小。

  • 数据的发送与确认:发送方根据窗口大小发送数据。每当接收方成功接收到一个数据段,它就会向发送方发送一个确认(ACK)报文,表明已成功接收到数据并准备好接收更多数据。

  • 窗口的滑动:随着数据被发送和确认,窗口会“滑动”。具体来说,当发送方收到一个确认报文时,它会将窗口的起始点向前移动到已确认数据的下一个未被确认的数据段。这样,窗口内就包含了新的未发送但可以发送的数据段。

  • 窗口大小的调整:滑动窗口的大小可以根据接受放的处理能力来进行流量控制。如果处理能力下降,接收方可能会减小窗口大小;如果状况良好,接收方可能会增大窗口大小,以允许更快的数据传输。

  • 数据的重传:如果发送方在一段时间内没有收到某个数据段的确认,它会假设该数据段丢失,并重新发送该数据段。重新发送的触发通常是基于一个计时器,该计时器会在发送数据段时启动,并在未收到确认时超时。图解 TCP 重传、滑动窗口、流量控制、拥塞控制 - 知乎 (zhihu.com)

[!note] 端口号范围
UDP和TCP报头使用两个字节存放端口号,所以端口号的有效范围是从0到65535。动态端口的范围是从1024到65535

2 UDP(无连接、尽最大努力、面向报文)

不可靠的、无连接的服务

image-20210917201002072
  • 校验和:校验和是为了提供可靠的 UDP 首部和数据而设计,防止收到在网络传输中受损的 UDP 包。

  • 多路复用/多路分解

  • 差错检测

2.1 特点

  • UDP是无连接的

  • UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的链接状态(这里面有许多参数);

  • UDP是面向报文的;

  • UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等);

  • UDP支持一对一、一对多、多对一和多对多的交互通信;

  • UDP的首部开销小,只有8个字节,比TCP的20个字节的首部要短。

3 TCP协议(面向连接、可靠、字节流)

无差错、不丢失、不重复、按序到达

[!note]
“面向字节流”的含义是:虽然应用程序和TCP的交互是一次一个数据块(大小不等),但TCP把应用程序交下来的数据仅仅看成是一连串的无结构的字节流。

3.1 TCP报文段结构

TCP(Transmission Control Protocol, 传输控制协议),可靠的、面向连接的服务

  • 面向连接:一定是「一对一」才能连接,不能像 UDP 协议可以一个主机同时向多个主机发送消息,也就是一对多是无法做到的;

  • 可靠的:无论的网络链路中出现了怎样的链路变化,TCP 都可以保证一个报文一定能够到达接收端

  • 字节流:用户消息通过 TCP 协议传输时,消息可能会被操作系统「分组」成多个的 TCP 报文,如果接收方的程序如果不知道「消息的边界」,是无法读出一个有效的用户消息的。并且 TCP 报文是「有序的」,当「前一个」TCP 报文没有收到的时候,即使它先收到了后面的 TCP 报文,那么也不能扔给应用层去处理,同时对「重复」的 TCP 报文会自动丢弃。(有点向Raft协议中将log从领导者复制到其他server)

image-20240314212340508
  • 序号:数据部分第一个字节的编号

  • 确认号:指明接收方下一次希望收到的报文段的数据部分第一个字节的编号

  • 窗口(16bit):接收窗口。用于告知对方(发送方)本方的缓冲还能接收多少字节数据。用于解决流控。

  • 校验和(16bit):接收端用CRC检验整个报文段有无损坏

应用程序的端口号和应用程序所在主机的 IP 地址统称为 socket(套接字),IP:端口号, 在互联网上 socket 唯一标识每一个应用程序,源端口+源IP+目的端口+目的IP称为”套接字对“,一对套接字就是一个连接,一个客户端与服务器之间的连接。

提供的服务

  • 差错控制

  • 流量控制:消除发送方使接收方缓存溢出的可能,速度匹配

  • 拥塞控制:发送方因IP网络的拥塞而被遏制

3.2 连接管理

image.png

  • FIN_WAIT_2:

    • 半关闭状态。
    • 发送断开请求一方还有接收数据能力,但已经没有发送数据能力。
  • CLOSE_WAIT状态:

    • 被动关闭连接一方接收到FIN包会立即回应ACK包表示已接收到断开请求。
    • 被动关闭连接一方如果还有剩余数据要发送就会进入CLOSE_WAIT状态。
  • TIME_WAIT状态:

    • 又叫2MSL等待状态。
    • 如果客户端直接进入CLOSED状态,如果服务端没有接收到最后一次ACK包会在超时之后重新再发FIN包,此时因为客户端已经CLOSED,所以服务端就不会收到ACK而是收到RST。所以TIME_WAIT状态目的是防止最后一次握手数据没有到达对方而触发重传FIN准备的。
    • 在2MSL时间内,同一个socket不能再被使用,否则有可能会和旧连接数据混淆(如果新连接和旧连接的socket相同的话)。

一个tcp连接需要:1,socket文件描述符;2,IP地址;3,端口;4,内存(读缓冲区、写缓冲区)

3.2.1 三次握手

同步序列编号(Synchronize Sequence Numbers)是 TCP/IP 建立连接时使用的握手信号三次握手能防止历史连接的建立,能减少双方不必要的资源开销,能帮助双方同步初始化序列

  • 客户端发送带有SYN的数据包到服务器端(SEQ=X)

  • 服务器为该TCP连接分配缓存和变量(SYN泛洪攻击),并向客户端发送SYNACK报文段(SEQ=Y, ACK=X+1)

  • 客户端收到SYNACK报文段,分配缓存和变量,对服务器允许连接的报文段进行确认(ACK=Y+1)

三次握手的原因: 、

  • 三次握手才可以阻止重复历史连接的初始化(主要原因)

  • 三次握手才可以同步双方的初始序列号

  • 三次握手才可以避免资源浪费

[!question] 两次握手和四次握手

两次握手:

  • 无法防止历史连接的建立:由于网络原因,客户端发送了多次SYN同步报文段,历史的SYN先到达服务器导致服务器建立连接,会造成双方资源的浪费

  • 无法同步双方序列号:服务器就客户端的初始序列号达成一致,但客户端还未就服务器的初始序列号进行确认四次握手:

  • 客户端发送SYN

  • 服务器收到SYN发送ACK

  • 服务器发送SYN

  • 哭护短收到SYN发送ACK
    其中,第二步和第三步可以优化为一步。三次握手就已经理论上最少可靠连接建立,所以不需要使用更多的通信次数。

3.2.2 四次挥手

image.png
  • 客户端发送FIN到服务端,发送关闭连接命令

  • 服务器收到FIN,发送ACK确认报文段(客户端没有数据要发,但服务器可能还未收到所有数据)

  • 服务器发送种植报文段FIN

  • 客户端进行确认,此时如果客户端等待 2MSL 后依然没有收到回复,就证明服务端已正常关闭,随后客户端也可以关闭连接了。

[!question] 为什么需要四次挥手
TCP 是全双工通信,可以双向传输数据。任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了 TCP 连接。

[!question] 为什么第四次挥手客户端需要等待 2*MSL(报文段最长寿命)时间后才进入 CLOSED 状态?第四次挥手时,客户端发送给服务器的 ACK 有可能丢失,如果服务端因为某些原因而没有收到 ACK 的话,服务端就会重发 FIN,如果客户端在 2*MSL 的时间内收到了 FIN,就会重新发送 ACK 并再次等待 2MSL,防止 Server 没有收到 ACK 而不断重发 FIN。在等待2MSL后没有收到重传FIN,则客户端认为服务器已经收到了ACK报文防止“已失效的连接请求报文段”出现在本连接中。 客户端在发送完最后一个ACK报文段后,再经过2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失,使下一个新的连接中不会出现这种旧的连接请求报文段。

[!note]
MSL(Maximum Segment Lifetime) : 一个片段在网络中最大的存活时间,2MSL 就是一个发送和一个回复所需的最大时间。如果直到 2MSL,Client 都没有再次收到 FIN,那么 Client 推断 ACK 已经被成功接收,则结束 TCP 连接

tcp - 经典问题:TIME-WAIT 时长为何为2 MSL? - the_blog - SegmentFault 思否

三次握手和四次挥手(附面试常问问题)-CSDN博客

TCP四次挥手及相关 - unclejac - 博客园 (cnblogs.com)

[!question] 为什么序列号随机生成

3.3 TCP保证可靠传输

[!question]

  • 通过序列号和确认号解决网络包的乱序和丢包问题
  1. 建立连接:通过三次握手建立连接,保证连接实体真实存在

  2. 序号机制:保证数据是按序、完整到达

  3. 合理分片:tcp会按最大传输单元(MTU)合理分片,接收方会缓存未按序到达的数据,重新排序后交给应用层。

  4. 数据校验:TCP报文头有校验和,用于校验报文是否损坏

  5. 确认和超时重传:如果发送一直收不到应答,可能是发送数据丢失,也可能是应答丢失,发送方再等待一段时间之后都会进行重传。在数据包丢失或延迟的情况下,重新发送数据包,直到收到对方的确认应答(ACK)。TCP 重传机制主要有:基于计时器的重传(也就是超时重传)、快速重传(基于接收端的反馈信息来引发重传)、SACK(在快速重传的基础上,返回最近收到的报文段的序列号范围,这样客户端就知道,哪些数据包已经到达服务器了)、D-SACK(重复 SACK,在 SACK 的基础上,额外携带信息,告知发送方有哪些数据包自己重复接收了)。

  6. 流量控制:当接收方来不及处理发送方的数据,能通过滑动窗口,提示发送方降低发送的速率,防止包丢失。

  7. 拥塞控制:网络层拥堵造成的拥塞,包括慢启动,拥塞避免,快速重传三种机制

  • 连接管理:即三次握手和四次挥手。连接管理机制能够建立起可靠的连接,这是保证传输可靠性的前提。

  • 序列号:TCP将每个字节的数据都进行了编号,这就是序列号。序列号的具体作用如下:能够保证可靠性,既能防止数据丢失,又能避免数据重复。能够保证有序性,按照序列号顺序进行数据包还原。能够提高效率,基于序列号可实现多次发送,一次确认。

  • 确认应答:接收方接收数据之后,会回传ACK报文,报文中带有此次确认的序列号,用于告知发送方此次接收数据的情况。在指定时间后,若发送端仍未收到确认应答,就会启动超时重传。

  • 超时重传:超时重传主要有两种场景:数据包丢失:在指定时间后,若发送端仍未收到确认应答,就会启动超时重传,向接收端重新发送数据包。确认包丢失:当接收端收到重复数据(通过序列号进行识别)时将其丢弃,并重新回传ACK报文。

  • 流量控制:接收端处理数据的速度是有限的,如果发送方发送数据的速度过快,就会导致接收端的缓冲区溢出,进而导致丢包。为了避免上述情况的发生,TCP支持根据接收端的处理能力,来决定发送端的发送速度。这就是流量控制。流量控制是通过在TCP报文段首部维护一个滑动窗口来实现的。

  • 拥塞控制:拥塞控制就是当网络拥堵严重时,发送端减少数据发送。拥塞控制是通过发送端维护一个拥塞窗口来实现的。可以得出,发送端的发送速度,受限于滑动窗口和拥塞窗口中的最小值。拥塞控制方法分为:慢开始,拥塞避免、快重传和快恢复

3.4 流量控制

[!note] 消息队列:消息堆积

流量控制是一种速度匹配服务,即发送方的发送速率与接收方应用程序的读取速率相匹配。与拥塞控制相比,流量控制是一种主动行为。
TCP 通过让发送方维护一个称为接收窗口(receive window)的变量来提供流量控制,接收窗口表明接收方还有多少可用的缓存空间。

  • LastByteRead :主机B 上的应用进程从缓存读出的数据流的最后一个字节的编号。

  • LastByteRcvd: 从网络中到达的并且已放入主机B 接收缓存中的数据流的最后一个字节的编号。

接收方主机B需满足:

  • 缓存无溢出:$LastByteRcvd-LastByteRead\le RecBuffer$

  • 接收窗口:$rwnd=RecvBuffer-[LastByteRcvd-LastByteRead]$

接收窗口rwnd动态变化,主机B 通过把当前的rwnd 值放入它发给主机A 的报文段接收窗口字段中,通知主机A 它在该连接的缓存中还有多少可用空间。

发送方主机A需满足:
$$
LastByteSent-LastByteAcked \le rwnd
$$

3.5 拥塞控制

在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种情况就叫拥塞。拥塞控制就是为了防止过多的数据注入到网络中,这样就可以使网络中的路由器或链路不致过载。拥塞控制所要做的都有一个前提,就是网络能够承受现有的网络负荷。

拥塞控制是一个全局性的过程,涉及到所有的主机,所有的路由器,以及与降低网络传输性能有关的所有因素。相反,流量控制往往是点对点通信量的控制,是个端到端的问题。流量控制所要做到的就是抑制发送端发送数据的速率,以便使接收端来得及接收

image.png

拥塞窗口cwnd、ssthresh(slow start threshold)

为了进行拥塞控制,TCP 发送方要维持一个 拥塞窗口(cwnd) 的状态变量。拥塞控制窗口的大小取决于网络的拥塞程度,并且动态变化。发送方让自己的发送窗口取为拥塞窗口和接收方的接受窗口中较小的一个。

TCP 的拥塞控制采用了四种算法,即 慢开始、 拥塞避免、快重传 和 快恢复。在网络层也可以使路由器采用适当的分组丢弃策略(如主动队列管理 AQM),以减少网络拥塞的发生。

  • 慢开始: 慢开始算法的思路是当主机开始发送数据时,如果立即把大量数据字节注入到网络,那么可能会引起网络阻塞,因为现在还不知道网络的符合情况。经验表明,较好的方法是先探测一下,即由小到大逐渐增大发送窗口,也就是由小到大逐渐增大拥塞窗口数值。cwnd 初始值为 1,每经过一个传播轮次,cwnd 加倍。(当发送方每收到一个ACK,拥塞窗口cwnd的大小就会加1)

  • 拥塞避免: 拥塞窗口 cwnd 「超过」慢启动门限 ssthresh 就会进入拥塞避免算法,拥塞避免算法的思路是让拥塞窗口 cwnd 缓慢增大,即每经过一个往返时间 RTT 就把发送方的 cwnd 加 1.

  • 快恢复: 在 TCP/IP 中,快速重传和恢复(fast retransmit and recovery,FRR)是一种拥塞控制算法,它能快速恢复丢失的数据包。没有 FRR,如果数据包丢失了,TCP 将会使用定时器来要求传输暂停。在暂停的这段时间内,没有新的或复制的数据包被发送。有了 FRR,如果接收机接收到一个不按顺序的数据段,它会立即给发送机发送一个重复确认。如果发送机接收到三个重复确认,它会假定确认件指出的数据段丢失了,并立即重传这些丢失的数据段。有了 FRR,就不会因为重传时要求的暂停被耽误。  当有单独的数据包丢失时,快速重传和恢复(FRR)能最有效地工作。当有多个数据信息包在某一段很短的时间内丢失时,它则不能很有效地工作。

[! note] 拥塞发生

  • 超时重传:ssthresh设为cwnd/2,cwnd重置为1(cwnd初始值)

  • 快速重传:发送方接收到3次同一个包的ACK,cwnd=cwnd/2,ssthresh=cwnd,进入快速恢复算法

计算机网络-61-80 | 阿秀的学习笔记 (interviewguide.cn)

3.6 TCP粘包、拆包

一个完整的业务可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这个就是TCP的拆包和粘包问题。

原因

1、应用程序写入数据的字节大小大于套接字发送缓冲区的大小.

2、进行MSS大小的TCP分段。( MSS=TCP报文段长度-TCP首部长度)

3、以太网的payload大于MTU进行IP分片。( MTU指:一种通信协议的某一层上面所能通过的最大数据包大小。)

解决方案

1、消息定长。

2、在包尾部增加回车或者空格符等特殊字符进行分割

3、将消息分为消息头和消息尾

4、使用其它复杂的协议,如RTMP协议等。

3.6.1 粘包

粘包的问题出现是因为不知道一个用户消息的边界在哪

  • 固定长度的消息

  • 特殊字符作为边界

  • 自定义消息结构(包头和数据,包头有一个字段指定数据大小)

TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。

  • 由TCP连接复用造成的粘包问题。

  • 因为TCP默认会使用Nagle算法,此算法会导致粘包问题。

    • 只有上一个分组得到确认,才会发送下一个分组;
    • 收集多个小分组,在一个确认到来时一起发送。
  • 数据包过大造成的粘包问题。

  • 流量控制,拥塞控制也可能导致粘包。

  • 接收方不及时接收缓冲区的包,造成多个包接收

解决

  1. Nagle算法问题导致的,需要结合应用场景适当关闭该算法

  2. 尾部标记序列。通过特殊标识符表示数据包的边界,例如\n\r,\t,或者一些隐藏字符。

  3. 头部标记分步接收。在TCP报文的头部加上表示数据长度。

  4. 应用层发送数据时定长发送

封包和拆包都是基于TCP的概念。因为TCP是无边界的流传输,所以需要对TCP进行封包和拆包,确保发送和接收的数据不粘连。

  • 封包:封包就是在发送数据报的时候为每个TCP数据包加上一个包头,将数据报分为包头和包体两个部分。包头是一个固定长度的结构体,里面包含该数据包的总长度。

  • 拆包:接收方在接收到报文后提取包头中的长度信息进行截取。

聊聊TCP协议的粘包、拆包以及http是如何解决的?_tcp拆包粘包-CSDN博客

3.7 半连接队列、全连接队列

服务器第一次收到客户端的 SYN 之后,就会处于 SYN_RCVD 状态,此时双方还没有完全建立其连接,服务器会把此种状态下请求连接放在一个队列里,我们把这种队列称之为半连接队列

当然还有一个全连接队列,就是已经完成三次握手,建立起连接的就会放在全连接队列中。如果队列满了就有可能会出现丢包现象。

这里在补充一点关于SYN-ACK 重传次数的问题: 服务器发送完SYN-ACK包,如果未收到客户确认包,服务器进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传。如果重传次数超过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。 注意,每次重传等待的时间不一定相同,一般会是指数增长,例如间隔时间为 1s,2s,4s,8s…
TCP实战(半连接队列、全连接队列) - 知乎 (zhihu.com)

3.8 TCP网络攻击方式,SYN flood攻击

  • SYN Flood攻击:这是一种利用TCP协议握手过程中的缺陷进行的攻击。攻击者发送大量的TCP SYN请求到目标服务器,但在收到服务器的SYN+ACK响应后并不发送最后的ACK确认,导致服务器上留下大量等待完成的半开连接,耗尽服务器资源,使得正常的TCP连接无法建立。

  • TCP会话劫持:这种攻击方式是通过窃取TCP会话中的序列号等信息,然后冒充合法用户接入到会话中。攻击者可以监听网络上的TCP会话,分析并预测序列号,然后发送伪造的数据包,中断或篡改原有的会话内容。

  • TCP重置攻击: 在这种攻击中,攻击者发送伪造的TCP RST(重置)数据包到目标主机,中断正常的TCP连接。由于TCP协议的设计,当接收到RST数据包时,连接的两端都会关闭连接,这使得攻击者可以成功地中断服务或进行拒绝服务攻击。

服务器端的资源分配是在二次握手时分配的,而客户端的资源是在完成三次握手时分配的,所以服务器容易受到SYN洪泛攻击。SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server则回复确认包,并等待Client确认,由于源地址不存在,因此Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。SYN 攻击是一种典型的 DoS/DDoS 攻击。

  • 缩短超时(SYN Timeout)时间

  • 增加最大半连接数

  • 过滤网关防护

  • SYN cookies技术

DDos攻击:客户端向服务端发送请求链接数据包,服务端向客户端发送确认数据包,客户端不向服务端发送确认数据包,服务器一直等待来自客户端的确认 没有彻底根治的办法,除非不使用TCP DDos 预防: 1)限制同时打开SYN半链接的数目 2)缩短SYN半链接的Time out 时间 3)关闭不必要的服务

应对SYN flood攻击

  • 启用SYN Cookie技术:SYN Cookie是一种无状态的TCP连接技术,它通过计算一个独特的Cookie来验证TCP连接的合法性,而不需要在服务器上保存每个连接的状态信息。当服务器收到SYN请求时,它会计算一个Cookie并发送给客户端,客户端在后续的ACK报文中携带该Cookie,服务器通过验证Cookie的有效性来判断连接是否合法。这样可以有效减少服务器资源的消耗,并防止SYN flood攻击导致的资源耗尽。

  • 调整TCP协议栈参数:通过调整TCP协议栈的参数,可以优化服务器的性能和防御SYN flood攻击。例如,可以减小SYN Timeout时间,使服务器更快地释放无效的连接请求;增大TCP连接的队列长度,提高服务器处理连接请求的能力;启用TCP Fast Open等特性,加快TCP连接的建立过程。

  • 使用防火墙或入侵检测系统(IDS):防火墙或IDS可以监控网络流量,并识别出异常的SYN请求流量。它们可以根据预设的规则对恶意流量进行过滤或限制,从而保护服务器免受SYN flood攻击的侵害。

Cookie技术:

  • 服务器生成初始TCP序列号(seq),该序列号是SYN 报文段的源和目的IP 地址与端口号以及仅有该服务器知道的秘密数的一个复杂函数(散列函数),发送SYNACK报文段

  • 客户端返回ACK(seq+1),运行一次相同的散列函数,如果hash()+1=ACK报文段的确认之

TCP 传输可靠性保障(传输层) | JavaGuide

[!note] 超时重传、RTO、RTT

  • 超时重传:发送端发送报文后若长时间未收到确认的报文则需要重发该报文。可能有以下几种情况:

    • 发送的数据没能到达接收端,所以对方没有响应。
    • 接收端接收到数据,但是ACK报文在返回过程中丢失。
    • 接收端拒绝或丢弃数据。
  • RTO:从上一次发送数据,因为长期没有收到ACK响应,到下一次重发之间的时间。就是重传间隔。

    • 通常每次重传RTO是前一次重传间隔的两倍,计量单位通常是RTT。例:1RTT,2RTT,4RTT,8RTT…
    • 重传次数到达上限之后停止重传。
  • RTT:数据从发送到接收到对方响应之间的时间间隔,即数据报在网络中一个往返用时。大小不稳定。

4 TCP与UDP区别

4.1 区别

  • 是否面向连接:UDP 在传送数据之前不需要先建立连接。而 TCP 提供面向连接的服务,在传送数据之前必须先建立连接,数据传送结束后要释放连接。

  • 是否是可靠传输:远地主机在收到 UDP 报文后,不需要给出任何确认,并且不保证数据不丢失,不保证是否顺序到达。TCP 提供可靠的传输服务,TCP 在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制。通过 TCP 连接传输的数据,无差错、不丢失、不重复、并且按序到达。

  • 是否有状态:这个和上面的“是否可靠传输”相对应。TCP 传输是有状态的,这个有状态说的是 TCP 会去记录自己发送消息的状态比如消息是否发送了、是否被接收了等等。为此 ,TCP 需要维持复杂的连接状态表。而 UDP 是无状态服务,简单来说就是不管发出去之后的事情了(这很渣男!)。

  • 传输效率:由于使用 TCP 进行传输的时候多了连接、确认、重传等机制,所以 TCP 的传输效率要比 UDP 低很多。

  • 传输形式:TCP 是面向字节流的,UDP 是面向报文的。

  • 首部开销:TCP 首部开销(20 ~ 60 字节)比 UDP 首部开销(8 字节)要大。

  • 是否提供广播或多播服务:TCP 只支持点对点通信,UDP 支持一对一、一对多、多对一、多对多

  • UDP是面向报文的,发送方的UDP对应用层交下来的报文,不合并,不拆分,只是在其上面加上首部后就交给了下面的网络层,论应用层交给UDP多长的报文,它统统发送,一次发送一个。而对接收方,接到后直接去除首部,交给上面的应用层就完成任务了。因此,它需要应用层控制报文的大小

[!tips]

  • UDP 一般用于即时通信,比如:语音、 视频、直播等等。这些场景对传输数据的准确性要求不是特别高,比如你看视频即使少个一两帧,实际给人的感觉区别也不大。
  • TCP 用于对传输准确性要求特别高的场景,比如文件传输、发送和接收邮件、远程登录等等。
TCP UDP
是否面向连接
是否可靠
是否有状态
传输效率 较慢 较快
传输形式 字节流 数据报文段
首部开销 20 ~ 60 bytes 8 bytes
是否提供广播或多播服务

4.2 TCP和UDP使用同一个端口号

TCP 和 UDP 传输协议,在内核中是由两个完全独立的软件模块实现的。当主机收到数据包后,可以在 IP 包头的「协议号」字段知道该数据包是 TCP/UDP,所以可以根据这个信息确定送给哪个模块(TCP/UDP)处理,送给 TCP/UDP 模块的报文根据「端口号」确定送给哪个应用程序处理。而在同一个协议内部,端口号必须是唯一的,以区分不同的应用程序。

因此, TCP/UDP 各自的端口号也相互独立,互不影响。

4.18 TCP 和 UDP 可以使用同一个端口吗? | 小林coding (xiaolincoding.com)

5 ARQ协议

自动重传请求(Automatic Repeat-reQuest,ARQ)是 OSI 模型中数据链路层和传输层的错误纠正协议之一。它通过使用确认和超时这两个机制,在不可靠服务的基础上实现可靠的信息传输。如果发送方在发送后一段时间之内没有收到确认信息(Acknowledgements,就是我们常说的 ACK),它通常会重新发送,直到收到确认或者重试超过一定的次数。

ARQ 包括停止等待 ARQ 协议和连续 ARQ 协议。