标准化通信

标准化通信是指在通信过程中使用一套统一的规则和标准,以确保不同系统、设备或应用程序之间能够有效地交换信息。

1.协议标准化

网络通信协议,如TCP/IP、HTTP、FTP等,定义了数据如何在网络中传输的规则。这些协议的标准化确保了不同设备能够理解和使用这些协议进行通信。

2.数据格式标准化

数据格式,如JSON、XML、CSV等,定义了数据结构化的方式。标准化的数据格式使得不同系统之间能够轻松地解析和生成数据。

3.字符编码标准化

如UTF-8、UTF-16等字符编码标准,确保了不同系统之间能够正确地处理和显示文本数据。

4.接口标准化

API(应用程序编程接口)的标准化确保了不同软件系统之间能够以一种一致的方式进行交互。

5.信号和传输标准化

在物理层,如以太网、Wi-Fi、蜂窝网络等,信号传输的标准化确保了不同设备能够使用相同的物理介质进行通信。

6.安全标准化

如SSL/TLS等安全协议的标准化,确保了网络通信的安全性。

7.国际标准化组织

ISO(国际标准化组织)、IEEE(电气和电子工程师协会)等,负责制定和发布各种技术标准。

ISO--七层参考模型

为什么分层?

1.更利于标准化;

2.每个层次之间可以独立的发展。

OSI模型的七层从上到下依次是:

应用层

这是最接近用户的一层,提供了网络服务与用户应用软件之间的接口.

【常见的应用层协议包括HTTP、FTP、SMTP等】

(人机交互的窗口)

表示层

这一层负责数据的转换和加密,确保数据在网络中传输前后的表示格式一致.

(例如,它可以将ASCII码转换为EBCDIC码,或者进行数据压缩和加密。)

(统一编码格式,将人类语言转换成二进制)

会话层

会话层负责建立、管理和终止两个通信系统之间的会话。它还负责检查点设置、恢复和同步。

(建立维护和断开一次会话通讯)

会话:主机和服务器之间建立的通道

1.提供会话层地址 (账号);

2。建立主机和服务器之间的逻辑通道。

传输层

传输层提供了端到端的数据传输服务,确保数据可靠、顺序正确地到达目的地。常见的传输层协议有TCP和UDP。

(端到端的传输,应用到应用之间的传输。利用传输层地址(端口号)进行应用和服务的区分)

端口号的本质是16位二进制,数量是65536个,取值范围0-65535 ,其中0作为保留端口号,实际范围1-65535

1-1023:知名端口号(著名端口号,SSH--22端口)

网络层

网络层负责数据包从源到目的地的路由和转发。它使用IP地址来识别网络中的设备,并决定数据包的最佳路径。

(通过IP地址实现逻辑寻址)

访问服务器的一些方式(获取目标服务器IP地址的方式)

1.直接获取到目标服务器的IP地址;

2.通过域名进行访问---DNS;

3.通过APP或者应用程序去获取;

4.通过广播获取。

数据链路层

这一层负责在相邻的网络设备之间传输数据。它将网络层的数据包转换为帧,并处理错误检测和纠正。

(通过MAC地址进行物理寻址)【MAC---在以太网种独有的地址】

物理层

物理层是OSI模型的最底层,负责在物理介质上传输数据。它定义了电气、机械和定时接口的规范。

(处理和传输电流信号)

TCP/IP协议簇

TCP/IP协议簇是互联网通信的基础,它不仅包括TCP(传输控制协议)和IP(互联网协议),还包括一系列相互关联的协议,如FTP(文件传输协议)、SMTP(简单邮件传输协议)等。这些协议共同构成了互联网数据传输的核心结构。

TCP/IP协议簇的组成和功能

TCP/IP协议簇通常被划分为四个层次,每个层次都有其独特的功能和协议:

  1. 应用层
    • 这是TCP/IP模型的最高层,直接为用户的应用进程提供服务。
    • 包括的协议有HTTP(超文本传输协议)、FTP、SMTP、DNS(域名系统)等。
    • 这些协议定义了数据在网络中的格式和传输方式,例如HTTP用于共享超文本数据,FTP用于文件传输,SMTP用于邮件传送,DNS用于域名解析。
  2. 传输层
    • 主要负责端到端的通信和数据完整性。
    • 主要协议有TCP和UDP(用户数据报协议)。
    • TCP提供可靠的、面向连接的服务,而UDP则提供一种不可靠的、无连接的服务。
  3. 网络层
    • 负责数据包的发送和接收,包括地址分配、路由选择等。
    • 主要协议是IP,它负责将数据分包并发送至目标地址。
  4. 链路层
    • 也称为网络接口层,负责物理传输的介质细节,如以太网、Wi-Fi等。
    • 这一层确保数据能够在物理媒介上正确传输。

TCP/IP协议簇的工作原理

  • TCP/IP协议簇的工作原理基于其分层模型。

  • 每一层协议都专注于自己的任务,共同实现高效和可靠的网络通信。

  • 数据从应用层开始,经过每一层协议的处理和封装,最终通过物理媒介传输到目标设备。

  • 在接收端,数据经过相反的过程,每一层协议依次解封装,最终将数据传递给相应的应用程序。

TCP/IP协议簇的应用案例

TCP/IP协议簇广泛应用于各种网络场景,例如:

  • Web浏览:使用HTTP协议在应用层进行数据传输。
  • 文件传输:使用FTP协议在应用层进行文件传输。
  • 邮件传送:使用SMTP协议在应用层进行邮件传送。
  • 域名解析:使用DNS协议在应用层进行域名解析。

PDU(协议数据单元)是指在特定通信协议下传输的数据单元。它代表了网络中不同层次的数据传输格式。

在OSI模型中,不同层次有不同类型的PDU:

应用层:数据报文

传输层:数据段

网络层:数据包

数据链路层:数据帧

物理层:比特流

封装与解封装

封装和解封装是TCP/IP协议簇中数据传输的两个核心过程。这两个过程分别在数据发送端和接收端进行,确保数据能够正确地从一个网络节点传输到另一个网络节点。

封装

封装是在数据发送端进行的。当应用程序准备发送数据时,数据会按照TCP/IP协议栈的层次结构从上到下依次传递,每一层都会对数据进行处理和封装。具体过程如下:

  1. 应用层:应用程序将数据传递给传输层。例如,一个HTTP请求或FTP命令。

  2. 传输层:在这一层,TCP或UDP协议会对数据进行处理。TCP会分割数据成小的数据段,并为每个数据段添加序列号。UDP则将数据分割成数据报。

  3. 网络层:在这一层,IP协议会对数据进行进一步的封装,形成IP数据报。IP数据报包含了源IP地址和目的IP地址等重要信息。

  4. 链路层:在这一层,数据被分割成帧,并添加了源MAC地址和目的MAC地址。帧是网络中实际传输的数据单元。

解封装

解封装是在数据接收端进行的。当数据到达目标设备时,数据会按照TCP/IP协议栈的层次结构从下到上依次传递,每一层都会对数据进行解封装。具体过程如下:

  1. 链路层:接收到的帧会被解封装,提取出MAC地址信息,然后将数据传递给网络层。

  2. 网络层:在这一层,IP数据报会被解封装,提取出IP地址信息,并根据目的IP地址进行路由。然后,数据被传递给传输层。

  3. 传输层:在这一层,TCP或UDP协议会对数据进行解封装。TCP会根据序列号重新组装数据段,确保数据的完整性和顺序。UDP则直接将数据报传递给应用层。

  4. 应用层:最终,数据被传递给目标应用程序,如Web浏览器或FTP客户端。

封装和解封装的过程确保了数据能够在复杂的网络环境中正确地传输和接收。

每一层协议都专注于自己的任务,共同实现了高效和可靠的网络通信。

STP生成树协议——跨三四层进行封装

OSPF——跨四层封装的协议【可以提升数据包转发效率】

协议及其对应的协议字段值【利用协议字段区分上层协议】

  • TCP(传输控制协议):协议号6

  • UDP(用户数据报协议):协议号17

  • OSPF(开放最短路径优先):协议号89

DHCP

DHCP动态主机配置协议)是一种应用层协议,它运行在UDP协议之上,并使用端口67和端口68进行通信。DHCP主要用于自动分配IP地址和其他网络配置参数给网络中的主机。以下是DHCP协议和端口使用的详细解释:

DHCP协议概述

DHCP(动态主机配置协议)允许主机自动获取IP地址、子网掩码、默认网关、DNS服务器地址等网络配置信息。这样,网络管理员就不需要手动配置每台主机的网络设置,大大简化了网络管理的工作。

DHCP工作原理

  1. 发现阶段:客户端发送广播消息(DHCPDISCOVER)来查找网络中的DHCP服务器。客户端使用68端口发送此消息。

  2. 提供阶段:DHCP服务器收到DHCPDISCOVER消息后,会从地址池中提供一个可用的IP地址,并通过广播消息(DHCPOFFER)发送给客户端。服务器使用67端口发送此消息。

  3. 请求阶段:客户端选择一个DHCPOFFER,并向DHCP服务器发送广播消息(DHCPREQUEST)来请求分配该IP地址。客户端仍然使用68端口发送此消息。

  4. 确认阶段:DHCP服务器收到DHCPREQUEST消息后,会发送一个广播消息(DHCPACK)来确认分配给客户端的IP地址。服务器使用67端口发送此消息。

端口使用

  • 端口67:DHCP服务器监听的端口,用于接收来自客户端的DHCPDISCOVER和DHCPREQUEST消息,并发送DHCPOFFER和DHCPACK消息。

  • 端口68:DHCP客户端监听的端口,用于接收来自服务器的DHCPOFFER和DHCPACK消息。

通过这种方式,DHCP协议能够自动为网络中的主机分配IP地址和其他必要的网络配置信息,从而简化了网络管理并提高了网络配置的灵活性。

首次获取ip地址

步骤 报文类型 从 -> 到 UDP端口号 源IP地址 目标IP地址 源MAC地址 目标MAC地址 描述
1 DHCP Discover 客户端 -> DHCP服务器 68 (源) -> 67 (目标) 0.0.0.0 255.255.255.255 客户端MAC FF-FF-FF-FF-FF-FF 客户端寻找网络中的DHCP服务器
2 DHCP Offer DHCP服务器 -> 客户端 67 (源) -> 68 (目标) 服务器IP 255.255.255.255 服务器MAC 客户端MAC/FF-FF-FF-FF-FF-FF DHCP服务器提供一个可用的IP地址
3 DHCP Request 客户端 -> DHCP服务器 68 (源) -> 67 (目标) 0.0.0.0 255.255.255.255 客户端MAC FF-FF-FF-FF-FF-FF 客户端请求IP地址,并通知其他DHCP服务器
4 DHCP ACK DHCP服务器 -> 客户端 67 (源) -> 68 (目标) 服务器IP 客户端的新分配IP 服务器MAC 客户端MAC DHCP服务器确认IP地址的分配

在次获取ip地址

租期--24h

T1时间---50%租期 12h

T2时间--87.5%租期 21H

步骤 报文类型 从 -> 到 UDP端口号 源IP地址 目标IP地址 源MAC地址 目标MAC地址 描述
1.3 DHCP Request 客户端 -> DHCP服务器 68 (源) -> 67 (目标) 客户端当前IP 服务器IP 客户端MAC 服务器MAC 客户端请求续租或获取新IP地址,发送单播请求报文到DHCP服务器
1.4 DHCP ACK DHCP服务器 -> 客户端 67 (源) -> 68 (目标) 服务器IP 客户端的新分配IP 服务器MAC 客户端MAC DHCP服务器确认IP地址的分配,发送ACK报文到客户端

ARP协议--地址解析协议

  1. 地址获取协议

    • 正向ARP:通过IP地址获取MAC地址。当主机需要发送数据帧到另一个网络的主机时,它会使用ARP来查询目标主机的MAC地址。
    • 反向ARP:允许主机通过其MAC地址获取IP地址。
    • 免费ARP:主机发送ARP请求以获取自己的IP地址对应的MAC地址,通常用于检测网络中是否有其他设备使用了相同的IP地址。
  2. 交换机转发

    • 交换机收到数据帧后,会根据接收该数据帧的接口和数据帧中的源MAC地址信息,更新MAC地址表。
    • 根据数据帧中的目标MAC地址进行转发。如果MAC地址表中存在目标MAC地址的记录,则直接单播转发;如果没有记录或者目标MAC地址是全FF(广播地址),则进行广播,即向除接收接口外的所有接口转发数据帧。
  3. 路由器转发原理

    • 路由器根据数据包中的目标IP地址和自身的路由表决定如何转发数据包。
    • 如果路由表中存在目标IP地址的记录,则直接转发;如果没有记录,则通常丢弃数据包。
  4. DNS

    • 域名解析协议,用于将域名(如www.baidu.com)解析为IP地址。
    • 域名结构:
    • 递归查询:当本地DNS服务器没有找到域名对应的IP地址时,它会向其他DNS服务器发起查询,直到找到为止。
    • 迭代查询:如果最近的DNS服务器没有查询到相应记录,它会返回一个参考地址,让查询者向该地址继续查询。
  5. URL

    • 统一资源定位符,用于定位网络上的资源,如https://www.baidu.com/。
  6. HTTP请求过程

    • 浏览器检查本地host文件和缓存,看是否有域名对应的IP地址记录。如果有,则直接封装HTTP数据报文;如果没有,则触发DNS解析。
    • 终端主机向服务器发起TCP三次握手,建立连接。
    • 终端发起HTTP请求,请求特定的资源。
    • 服务器根据请求的资源目录,进行回复,发送HTTP响应。
    • 四次挥手,断开服务器和终端的TCP会话。

TCP

TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流传输的协议。它工作在OSI模型的传输层,主要用于在网络上传输数据。下面是对您提到的几个关于TCP的问题的详细解释:

  1. 面向连接:TCP是一种面向连接的协议,这意味着在数据传输开始之前,需要在两个通信端点之间建立一个连接。这个过程通常被称为“握手”,确保了数据传输的初始化和同步。

  2. 基于字节流传输数据:TCP将数据视为一连串无结构的字节流。这意味着发送端可以不断发送数据,而接收端则可以按照接收的顺序来处理这些数据。

  3. 区分TCP流:每个TCP连接由一个四元组唯一标识,这个四元组包括源IP地址、源端口号、目的IP地址和目的端口号。这确保了在复杂的网络环境中,每个TCP连接都能被唯一识别。

  4. 确保数据传输可靠性:TCP通过多种机制来确保数据传输的可靠性,包括:

    • 排序:TCP对发送的数据进行分段,并为每个分段分配一个序号。接收方根据这些序号重新组装数据,确保数据的完整性。
    • 确认:接收方会发送确认信息(ACK)来确认已成功接收的数据。
    • 重传:如果发送方没有收到确认信息,它会假设数据丢失或出错,并重新发送数据。
    • 流控:TCP使用流量控制机制,如滑动窗口协议,来控制数据传输的速率,避免网络拥塞。
  5. 三次握手:这是TCP建立连接的过程,包括三个步骤:

    • SYN:发送方发送一个SYN(同步序列编号)报文段到接收方,开始一个连接的初始化。
    • SYN-ACK:接收方收到SYN报文段后,发送一个SYN-ACK报文段作为应答。
    • ACK:发送方收到SYN-ACK报文段后,发送一个ACK报文段作为应答。
  6. TCP的报文结构:TCP报文包含首部和数据两部分。首部包含了源端口、目的端口、序列号、确认号、数据偏移、保留、标志位(如SYN、ACK、FIN等)、窗口大小、校验和、紧急指针等字段。数据部分则是实际传输的应用程序数据

TCP的三次握手

连接建立过程中的状态变化SYN标志位。你当SYN置为1,就说明我这个报文是一个建立连接到的数据报文)

seq序号是随机的,目的是防止报文的乱序和旧有报文对现在数据造成的影响。

TCP第三次握手的数据包允许客户端携带数据

正常的三次握手建立过程,我们刚才已经说完了。我们观察这张图发现,两边还写了一些close,listen之类的标识。其实,TCP连接在建立的过程中,也是可以分为不同的阶段的。不同阶段,我们客户端或者服务器的状态都不尽相同,所以,我们使用不同的状态来进行标识。

我们先从客户端的角度来看下状态的变化。

  1. 一开始,在还没有发送建立请求之前,客户端处于Closed(关闭)状态。在发送完SYN请求报文段之后,将进入到下一个状态;
  2. 发送完SYN请求报文段后,客户端将处于SYN_Sent状态。在这个状态下,客户端在等待服务器返回SYN+ACK报文段;
  3. 当客户端收到服务器发送的SYN+ACK报文段后,则将进入到最后的Established(建立完成)状态。因为此时客户端指向服务器的会话就已经建立好了,所以,客户端发送的最后一个ACK报文就可以携带数据了。

我们再从服务器的角度看下状态的变化。

  1. 服务器一开始也是处于Closed(关闭)状态。当服务器的应用程序创建一个监听套接字之后,将进入到Listen(监听)状态。
  2. 之后,服务器将等待客户端发送的SYN请求报文段。收到后,将回复SYN+ACK报文段。回复之后将进入到SYN_RCVD状态。之后等待客户端的ACK报文。
  3. 服务器接收到客户端发送的ACK报文之后,将进入到最后的状态Established(建立完成)状态。也标着着服务器指向客户端的会话建立完成。至此,整个TCP的双向会话均建立完成。

TCP的异常连接

我们上面讨论的都是假定客户端和服务器都已经准备好的情况下,但如果连接情况没有那么顺利该怎么办呢?

例如,假如一台主机接收到一个TCP SYN报文段,里面的目的端口号是80端口。但是,该主机80端口并不接受连接,可能是因为它并没有运行web服务器。

在这种情况下,主机就会给发送源发一个TCP报文段,将其中的RST标记位置1。用来中断这次连接。(一般发送到一个无效的TCP连接时,都会使用RST报文段来终止)。

TCP链接断开

当TCP的连接建立完成后,我们就可以尽情的通过TCP连接所创立的会话来进行数据的传输了。当然,再有意思的话题也有说完的时候,所以,当数据传输完之后,TCP该如何善后呢?

TCP的四次挥手

TCP的连接断开需要经历4次数据包的交互才能完成,所以这个过程我们习惯性的称为“四次挥手”。当然,结束连接之后,主机中的"资源"(即缓存和变量)也就被释放掉了。

断开连接过程中的状态变化

同样,这个图中,也标识出了断开过程中客户端以及服务器的状态变化。我们还是分别从客户端和服务器的视角来看一下这个状态变化。

我们还是先从客户端的角度出发,来观察下这个状态变化。

  1. 客户端一开始,还处于ESTABLISHED建立的状态,现在,他发现它数据传递完毕,于是发送了FIN断开请求报文段,之后,变进入到了一个新的状态 --- FIN_WAIT_1。
  2. 客户端再FIN_WAIT_1状态下,就是在等待服务器回复ACK,一旦等到之后,将进入到下一个状态。
  3. 客户端在收到服务器发送的ACK之后进入的状态被称为FIN_WAIT_2状态。这个状态主要就是等待服务器发送FIN请求。
  4. 客户端在收到服务器发送的FIN断开请求之后,将回复ACK进行确认。但注意,客户端并没有直接断开连接,进入到CLOSE(关闭)状态,而是进入到了一个TIME_WAIT状态继续等待。
  5. 在这个TIME_WAIT状态等待2MSL(这是一个时间),之后进入CLOSE(关闭)状态。进入到关闭状态后客户端将释放掉所有给这个TCP连接分配的资源。

以上便是客户端在断开连接过程中出现的状态变化。注意,服务器也可以主动发起断开,则服务器方的状态变化也将经历这几个过程。

下来我们再开看下服务器方的状态变化。

  1. 首先,服务器也还处在ESTABLISHED建立的状态。在收到客户端的FIN断开请求后,服务器会回复一个ACK进行确认,同时进入到CLOSED_WAIT状态。
  2. 这个状态随着服务器自身发送FIN断开请求报文段之后,将结束,并进入到一个新的状态 --- LSAT_ACK状态。
  3. 从这个状态的名字就可以看出来,服务器在等待最后的一个ACK报文段。当服务器接收到这个ACK之后,则将进入最终的状态,也就是CLOSE(关闭)状态。之后,将给这个TCP连接分配的所有资源释放掉。

以上便是整个“四次挥手”断开过程的状态变化。需要注意的就是,这里的客户端和服务器是相对的,先发送FIN的需要经历“客户端”那一套,也就是需要在关闭前进行等待。而被动方则走的是“服务器”那一套,再收到ACK报文之后直接关闭。

为什么需要有TIME_WAIT状态

不出意外的话,再看过TCP断开的四个过程中的状态变化之后,大家可能都会有一个疑问,就是这个FIN的发起方为啥需要等待一段时间之后,才能关闭TCP连接?也就是这个TIME_WAIT状态存在的意义是什么?

其实这是很重要的一个等待,因为他是我们连接能够正常被关闭的保证。

我们先假设没有TIME_WAIT或者这个时间过短,看看会发生什么样的事情。

从旁边的图中,我们其实就已经可以清楚的看出这个等待的必要性了。因为我们永远不能以最理想的眼光来看待网络通信。说不定,那个数据包就迷失在这网络数据之海中了。

这里假设客户端发送的最后一个ACK在网络中丢失了,而我们客户端不等待或者等待时间很短,则将自顾自的关闭了TCP连接。但是,服务端没有收到最后的确认,则一直停留在了LAST_ACK状态了。这样很不负责任。

服务器长时间接收不到ACK,则也将触发重传(TCP的可靠之处了),服务器会再发送一个FIN断开请求。而此时,客户端已经关闭了该连接通道,则将回复RST来终结连接,这就属于异常的断开。

TCP确保数据可靠传输:排序 确认 重传 流控

重传机制

那如果在本端发送完数据段之后,并没有收到对端反馈的确认报文呢?这时候,就需要使用到重传机制了,既然我已经有理由怀疑你没有收到,那我再发你一遍不是最基本的操作吗?

RTT和RTO

重传机制中有一个很重要的点,就在于到底多长时间没有收到你的确认报文段,我才去重传。这种重传机制我们称为超时重传。(重传不一定只是在超时的情况下出现,这个我们后面再看)

当然,超时重传的这个时间是非常重要的一个参数,那这个时间到底应该设置为多少呢?我们需要先理解一个和时间相关的参数 --- RTT(*Round-Trip Time)往返时间

RTT往返时间 --- 指的是发出端将数据发出后,到他接收到对端反馈的确认报文之后的这一段时间。

超时重传的这个重传时间,我们称为RTO(Retransmission Timeout 超时重传时间)。这个时间就是我们这里需要仔细关注的时间,而这个时间和我们刚才说的这个RTT往返时间是有密切关系的。

这里,我们可以思考下,这个重传时间过长或者过短,会发生哪些情况。

先看第一种情况,就是如果当超时时间比较大。其实这种情况带来的问题非常显而易见,那就是丢包之后,重传的效率会降低,无法及时响应。

那如果重传时间设置的过小呢?如果这个时间比较短,甚至比我们RTT时间还要短,那就有可能造成不必要的重传,可能人家也正常收到了数据包,也正常回复的确认报文,只是因为这个报文还没有到达本端,本端就重新发送一遍。这样不也是资源的浪费嘛。

所以这个RTO的取值应该略大于RTT,但是也不能大太多。

这个值具体是需要通过RTT来进行计算的,并不是一个固定值。因为RTT的时间也并不都固定。至于其中的算法,我们就不去过细的研究了,我们记住这个RTO是一个动态变化的值就可以了。

在这个超时重传中,还有一个非常有趣的机制,就是超时间隔加倍。

拿上边的图举个例子,客户端发送序列号为100的一个数据段,服务器收到后,正常的回复ACK确认报文。但遗憾的是,这个确认报文在网络传输过程中,被淹没在数据洪流中了。客户端并没有收到服务器反馈的确认报文段。于是,在等待了RTO一个超时间隔后,客户端决定重发序列号为100的这个报文段。但是,这次的情况和上次一样,服务器回复的ACK依然没能正常的到达客户端。客户端只能继续等待超时间隔之后重发。只不过,这次的超时间隔时间将是第一次的2倍。也就是说假设第一次RTO = 0.5S,则第二次的RYO = 1S。

如果运气不好,重传的数据包还是没有收到确认的话,则这个翻倍机制将继续延续,下次的RTO = 2S了。(注意,这里都是重传同一个数据包的时候出现的情况哈。)

这个机制设计出来主要是和拥塞控制有点关系。这里的逻辑我们可以稍微盘一下。因为定时器超时导致的重传,最有可能造成这样结果的就是网络环境拥塞导致的。在这样的拥塞情况下,如果还是不停的去重传报文段,只会使拥塞加重。所以,TCP采用了这种超时间隔加倍的方式,来缓解这一点。

快速重传机制

超时重传的问题就是这个超时间隔会越来越长,这样超长时间的重传间隔,会加重端到端之间的时延。

好在,在TCP中,发送方可以通过接收方的反馈,在超时时间到达前,意识到数据包丢失的现象发生了,并进行重传。

这种情况出现在接受端收到一个失序报文的情况下。

什么是失序报文呢?简单来说,就是接受方在收到一个数据段中的序列号大于自己期望的序列号,这样的报文就是一个失序报文,这就说明自己期望的报文可能在茫茫网海中丢失了。

用左边的图再说明一下这个失序报文的问题。客户端发送了序号为100,200,300,400的报文,之后等待服务器的确认。(注意,在TCP中并不是严格的只发一个报文等待对方回复,这样效率太低,所以,我们会一次性多发几个报文再等待回复,这个发送量和窗口值有关,我们在流控的时候会详细讲解。)服务器收到序号为100的报文之后回复ACK,其中的确认序列号为200。可是,之后服务器这边并没有如愿的收到序号为200的数据报文段,而是收到了序号为300的报文段。那这种情况对于服务器来说,就是接收到了失序报文了。

这种情况下,服务器将意识到自己期望的报文段丢失了,所以,他不能直接确认后面的报文段,因为我们知道,TCP的确认是累计确认,也就是说,如果客户端收到服务器发送的确认序号为300的数据报文段,则客户端会任务300之前的字节流均已经传递完毕,并被接收了。则他将意识不到此时报文段丢失的问题。所以,这种情况下,服务器需要想办法让客户端知道报文段已经丢失了。但是,TCP不能直接发送一个否定确认(就是指没有办法直接发送一个数据报文段,告诉对端自己哪个报文没有接收到。)所以,TCP将采用冗余ACK(Duplicate ACK)的方式来完成这次通告。

所谓冗余ACK就是服务器将会通过再次发送携带确认序列号未丢失报文序号的确认报文,并且连续发送三次。(如上图所示)TCP就是通过这种方式来告知对端,这个报文已经丢失了,期待对方重传。

当客户端这边接收到3次冗余ACK之后,将意识到此时序号为200的报文段已经走失,需要重传。注意,这个时候的重传并不是因为RTO时间到达而触发的,这种重传是已数据包为驱动的一种重传机制,我们将这种重传称为快速重传机制。

这种重传会在定时器超时之前重传报文段,就可以解决超时重传时延加重的问题。

下面的图是抓包看到的快速重传的现象图。

流量控制

说到TCP的流量控制,它其实应该是属于TCP可靠性保障的一环,只不过其中涉及的知识点,值得我们单独拉出来好好的研究一下。

滑动窗口:累计确认

而要谈及流量控制,就不得不说一下TCP头部中的一个变量,那就是“窗口值”了。这个窗口值应该算是TCP实现流控的一个核心参数。

我们知道,TCP的传输为了保证可靠性,要求每发一个数据,就要得到一次确认应答。只有收到了之前数据包的确认之后,才会发送之后的数据包。很明显,这样的传输效率并不高。如果,你发送了一个信息到对端,但是对方此时可能并没能及时处理这个信息,那你就需要一直干等。这样将导致数据包的往返时间越长,通信的效率就会越低。

所以,何不趁多方忙别的时候,自己多发几个数据包呢?为此,我们专门引入了一个变量,那就是窗口。这个窗口的大小是可以指定的,窗口大小指的就是无需等待确认应答,而可以继续发送数据包的最大值。

窗口的大小,其实体现的就是缓存区的大小。我们前面说过,TCP双方都将为这个TCP连接建立缓存区域。发送方在发送数据的时候,在没有接收到对方的确认报文之前,发送的数据需要暂时存放在缓存区。而接受方,在接收到数据来不及处理,也需要暂存在缓存区。所以,窗口的大小需要充分考虑缓存区的大小才行。

这里我们给一个场景,假设窗口的大小是3个TCP报文段的大小。那其效果就是,发送方(我们以客户端作为发送方)可以一次性的发送三个TCP报文段,之后等待对方的确认。接收方(假定服务器方)理应针对这三个报文段进行确认,但实际上,中间的确认报文段就算丢失,也问题不大,不会触发重传,因为之前我们就说过,TCP是累计确认,只要收到最后的确认报文就相当于将前面的内容都确认了。

其实窗口值的用法是比较好理解的,主要是,这个参数是如何进行流控的?前面说了,这个窗口值的大小反应的是缓存区域的大小,所以这个参数并不是一成不变的。

TCP要求发送方依据接收窗口(receive window)--- rwnd来控制数据的发送量。这个接收窗口,其实反应的就是接受方此时缓存空间可用的大小,通过接收方发送数据包中的窗口值这个变量来携带。当然,因为TCP本身是一个全双工的通信协议,所以,通信双方都各自需要维护一个接收窗口。

我们现在假设客户端给服务器发送信息(我们只看一边),假设服务器为连接分配的缓存空间用RcvBuffer来表示其大小。服务器上的进程会从这个缓存区域中读取数据。从网络中到达并放入服务器缓存空间中的数据量减去服务器进程已经读取的数据量必须要小于我们整个的RcvBuffer,才能保证缓存区不溢出。而RcvBuffer减去他们之间的差值便是rwnd。 --- 这个空间就是随时间变化的,所以,rwnd也是随时间变化的。

服务器就是将当前的rwnd值放入发送给客户端的报文窗口字段,来通知客户端他在该连接中还有多少缓存空间可用。(开始时,rwnd == RcvBuffer)

而客户端需要保证的就是发送的字节最大序号减去本端收到的最后确认的序号值小于rwnd。(其实就是发出还没有确认的数据量)这样才能保证服务器接收数据时不会溢出。

也正是这样可变的窗口流控机制,我们称之为滑动窗口机制。

怎么预估窗口大小这个具体值呢?

你可以使用监控工具,比如Wireshark ,自己统计等。或者用计算的方式

基于带宽-延迟积

带宽-延迟积(BDP)是一个常用的计算方法,用于确定适当的TCP窗口大小。计算公式如下:

[ \text{窗口大小(字节)} = \text{带宽(字节/秒)} \times \text{往返时间(RTT)(秒)} ]

例如:

带宽为100Mbps(12.5MB/s)

RTT为50ms(0.05秒)

计算得出:

[ \text{窗口大小} = 12.5 \times 0.05 = 0.625 \text{MB} = 625 \text{KB} ]

小窗口处理

在看TCP流控相关的文章的时候,看到了这样的一种特殊情况,很有意思。如果接受方需要处理的数据比较多的情况下,就会导致窗口值越来越小。到最后,如果接受方只能腾出几个字节的窗口,而发送方将只能发送几个字节。

我们知道,光我们协议封装的头部,都需要占用几十个字节(比如TCP+IP头部最短就有40个字节),如果只传输几个字节的数据的话,那这个传输的经济性,则将大打折扣。

所以,在这种情况下,应该避免接受方通告小的窗口,而发送方,也应避免发送小的数据。

接收方一般采取的策略是设定一个窗口通告的最小值。这个最小值通常选择MSS或者1/2缓存空间这两个值中较小者。当窗口值小于其二者较小者的值时,将通告窗口值为0。直到窗口大小突破那个最小值之后,再打开窗口。

而发送方一般的策略是启用延时处理,只有在满足以下两个条件中任意一个时,才会发送数据,否则,将一直囤积数据,直到满足任一条件为止。

条件一:要等到窗口大小 >= MSS 并且 数据大小 >= MSS;

条件二:收到之前发送数据的ack回包;

TCP的拥塞控制

TCP的拥塞控制是TCP当中的一个难点。很多人不太理解,为什么TCP有流控,还有个拥塞控制,这两个到底有啥区别?

通过前面我们对TCP流控的简单介绍,因该能理解,流控主要是为了防止发送方发送流量过大导致接收方缓存区溢出的问题。而拥塞控制,则主要是受网络环境的影响。TCP也会观察网络的拥堵情况,如果网络拥塞严重的话,则将降低发送量,以缓解网络拥塞情况,这种行为属于TCP的拥塞控制。

大体的思路其实比较好理解,但是这句话其实就抛出了两个问题。

  1. 第一个问题就是,TCP是如何判断此时网络环境拥塞的;
  2. 第二个问题就是,TCP该如何去控制数据的发送量。(准确的说,如果一个TCP发送方感知从它到目的地之间的路径上没什么拥塞,则TCP发送方增加其发送速率;如果发送方感知沿着该路径有拥塞,则发送方就会降低其发送速率。)
TCP拥塞判断

那我们一个一个来,我们先来说下TCP到底是如何感知到此时网络中出现了拥塞的情况呢?

其实拥塞判断的问题,我们前面在可靠性里面已经提及过一些。TCP将连接中出现的丢包行为,视为拥塞的表现。这个其实很合理,一般数据包会丢失或者超时,大概率都是因为网络拥堵导致。当然,丢包事件可以通过两种形式体现:

1.其一就是数据包确认超时

2.其二就是收到来自接受方发送的3个冗余ACK

TCP拥塞控制

因为发送方需要根据网络的拥塞情况来调控发送的速率,所以,发送方需要额外的维护一个变量,我们称为拥塞窗口(congestion window)--- cwnd。他和rwnd(接收窗口)一样,都可以对发送的字节数大小进行限制。也就是说,发送方发送多少数据,其实同时受rwnd和cwnd共同影响。发送方中,发出未收到确认的字节数必须小于或等于rwnd和cwnd中的最小值。所以,TCP发送方可以通过限制cwnd来间接的影响发送速率,实现调控效果。

TCP拥塞控制算法

当然,这个参数到底该如何使用,什么情况下该做什么样的调整,实际上是有专门的拥塞控制算法来进行操控的。

在了解具体的算法之前,我们需要明确一点思路,那就是太过保守的TCP传输反而会导致无法充分利用带宽。TCP被称为是自计时(self-clocking)的,就是因为他会通过确认来增大拥塞窗口。这个怎么理解呢?在不存在拥塞的情况中,TCP将收到的确认报文后会认为道路畅通,从而增加窗口的长度,其实就是在向上试探,以追求更高的传输速率。如果确认到达的慢,那么拥塞窗口的增加速率也会很慢;如果响应很及时,确认到达的很快,则拥塞窗口增加的也会很快。

下来看下具体拥塞控制算法。这个算法主要包括三个部分 --- 慢启动,拥塞避免,快速恢复。

慢启动(slow - start)

TCP的连接在刚开始建立的时候,并不会直接以很大的传输速率来工作,因为并不清楚此时的网络情况,直接大量传输那不是胡闹嘛。通常,cwnd一开始会被设置成很小的一个值,一般等同于一个MSS,即一次只能发送一个数据报文段。但这个速率需要在短时间内提升起来,这就是慢启动的过程。

慢启动的做法也是非常简单的,就是每收到一个新的ACK确认报文(重传的确认不算在内),就会增加一个MSS的大小。(这就是前面说的,TCP会根据确认来增大拥塞窗口)

所以,慢启动其实是一种快速提升传输速率的方式(不能被名字误导),因为其呈现的是指数增长。(图中拥塞窗口的数值单位为MSS)

为了防止拥塞窗口cwnd增长过大造成网络拥塞,我们有不能一直处于慢启动状态。那他该如何停止呢?我们会设置一个慢启动门限(ssthresh)来做评定。

当cwnd < ssthresh时,使用慢启动算法;

当cwnd > ssthresh时,使用拥塞避免算法;

当cwnd = ssthresh时,既可以使用慢启动算法,也可以使用拥塞避免算法。

PS:ssthresh---慢启动阈值,一般等于当前窗口值的一半

拥塞避免

那下来咱们就讨论下这个拥塞避免算法是如何计算的。其实拥塞避免的思路也是很简单的,就是不能再像之前一样,高速上升了,我们需要把上升的速度降缓。以前慢启动的时候,我们是一个RTT时间内(RTT就是前面说过的往返时间,如果cwnd是4个报文段,那RTT就是发送方连续发送4个报文段之后,并收到4个确认这个过程所消耗的时间。),收到几个ACK,cwnd就增加几个MSS。而到了拥塞避免中,一个RTT时间内,cwnd就只增长一个MSS。从慢启动的指数增长变为了线性增长,增长速度明显变缓了。

注意,还是不能被这个名字所误导,拥塞避免也不是说就可以直接避免拥塞,而是通过降低窗口的增大速率而使网络不容易出现拥塞。

(这里假设设定ssthresh为8)

快速恢复

拥塞避免的增长到啥时候结束呢?如果没有出现拥塞的情况,那最好是可以一直增加下去的。但如果出现了拥塞,那这个增长就必须停止了。

当然,拥塞判断前面咱们说了,有两种方法,出现这两种情况,我们做出的处理方案是不一样的。

我们可以根据这张图片来进行分析。这里我们我们设置初始的ssthresh为16个报文段。一开始,cwnd执行慢启动算法,cwnd程指数上涨,很快就来到了ssthresh的门限值。也就是图中的①点。这里将结束慢启动,开始进入到拥塞避免算法。可以看出来增长速度明显变缓。

变故出现再②点,假设此时的拥塞窗口是24(单位MSS),发生了超时重传的情况。这是我们判定网络出现拥塞的一种现象。这时候,我们会将ssthresh值设定为cwnd的一半(即ssthresh = cwnd / 2 = 24 / 2 = 12)。之后,将cwnd设置为1。之后,重新开始慢启动和拥塞避免的过程(他们之间的门限值就是12了。) --- 这是针对超时重传的设定。

如果网络不会再发生拥塞,那这次的拥塞避免也应该一直执行下去,但是,变故又出现在了④点,此时cwnd是16。这时候,出现的是3次冗余ACK。这也是我们判定此时网络存在拥塞的一个依据,不过,在TCP眼中,这种情况并没有超时重传严重。因为此时并不一定网络真的存在拥塞,可能只是数据包丢失了。这时如果直接把cwnd降到1,感觉有点亏。所以,这种情况下(快速重传),我们采取的处理方案是 --- 使用快速恢复算法。

快速恢复的做法也很简单,就是直接将ssthresh设置为cwnd的一半(即ssthresh = cwnd / 2 = 16 / 2 = 8),同时将cwnd也设置为8(相当于也降低了一半),之后,直接开始拥塞避免。

这里需要注意一下,也有快速恢复实现会把初始的cwnd值在加3个MSS长度。相当于新的cwnd初始值为ssthresh + 3。(上面例子就是8 + 3 = 11)。这样做的理由是:既然发送方收到了3个重复的确认,就证明有3个分组已经离开了网络。这三个分组不再消耗网络资源而是停留在对方缓存中,所以,并没有堆积在网络里,那就可以适当的再加大一些窗口。

  1. TCP分段:TCP分段是将大量数据分割成较小的段,这样可以更有效地利用网络资源。每个TCP段由序列号唯一标识,并且可以在网络中独立路由。分段可以减少服务器和链路资源的浪费,因为它们允许更细粒度的流量控制和错误处理。

  2. MSS(最大段长度):MSS是TCP分段中的一个重要参数,它指定了TCP段中数据部分的最大长度。MSS的值通常由发送方和接收方在建立连接时协商确定。MSS的确定考虑了网络设备的MTU,以确保TCP段加上IP头部后不会超过MTU限制。

  3. MTU(最大传输单元):MTU是网络接口层(通常是数据链路层)可以传输的最大数据包大小。以太网网络的默认MTU通常是1500字节。如果一个数据包超过了MTU,它将被分片,这可能会导致性能下降和网络延迟。

  4. 数据单位转换

    • 1 Gigabit (G) = 1,000 Megabits (M)
    • 1 Megabit (M) = 1,024 Kilobits (K)
    • 1 Kilobit (K) = 1,024 bits
    • 8 bits = 1 byte

注意:在数据通信中,通常使用的是十进制前缀(如1 Gigabit = 1,000,000,000 bits),而在计算机存储中,通常使用的是二进制前缀(如1 Gigabyte = 1,073,741,824 bytes)。

园区网

1.园区网络分类

1.1 根据网络规模(园区本身)进行区分

1.2根据企业用户需要进行划分

1.3园区网络发展的问题

三层架构

  1. 接入层

    • 功能:提供用户或设备接入网络的接口。
    • 特点:通常包括交换机、无线接入点等设备,用于连接终端设备,如电脑、打印机等。
  2. 汇聚层

    • 功能
      • 提供汇聚网关,连接接入层和核心层。
      • 运行路由协议,实现不同业务部门之间的互相访问。
      • 通过聚合来自接入层的数据流量,降低核心层的压力。
    • 特点:通常包括路由器、多层交换机等设备,用于实现网络流量的汇聚和分发。
  3. 核心层

    • 功能
      • 实现整个企业内网所有业务网之间的互相访问。
      • 实现内外网的通讯。
    • 特点:通常包括高性能路由器、交换机等设备,用于高速处理和转发网络流量。

二层架构

  • 接入层:与三层架构中的接入层功能相同。
  • 汇聚层/核心层合并
    • 功能:将汇聚层和核心层的功能合并到同一层,简化网络结构。
    • 特点:适用于小型或中型企业,网络规模不大,可以减少设备数量和复杂性。

冗余设计

在企业网络设计中,冗余是确保网络高可用性的关键因素。冗余设计包括:

  1. 线路冗余:使用多条物理线路,确保一条线路故障时,流量可以自动切换到备用线路上。
  2. 设备冗余:部署备用设备,如路由器、交换机等,以防主设备故障。
  3. 网关冗余:使用多个网关设备,确保一个网关故障时,网络连接不会中断。
  4. UPS冗余(电源冗余):使用不间断电源(UPS)系统,确保网络设备在电源故障时仍能正常运行。
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐