计算机网络基础知识

计算机网络基础知识

概述

协议与划分层次

​ 在计算机网络中要做到有条不紊地交换数据,就必须遵守一些事先约定好的规则。这些为进行网络中的数据交换而制定的规则、标准或约定称为网络协议。

​ 网路协议主要由以下三个要素构成:

  • 语法,即数据与控制信息的结构或格式
  • 语义,即需要发出何种控制信息,完成何种动作以及做出何种响应
  • 同步,即事件实现顺序的详细说明

​ 对于复杂的计算机网路协议,其结构应该是层次式的,分层能带来很多好处,如:

  • 各层之间是独立的。某一层并不需要知道它的下一层是如何实现的,而仅仅需要知道该层通过层间的接口所提供的服务。由于每一层只实现一种相对独立的功能,因而可将一个难以处理的复杂问题分解为若干个较容易处理的更小一些的问题。
  • 灵活性好。当任何一层发生变化时,只要层间接口关系保持不变,那么在这层以上或以下各层均不受影响。
  • 结构上可分隔开。各层都可以采用最适合的技术来实现。
  • 易于实现和维护。这种结构使得实现和调试一个庞大而又复杂的系统变得更加容易,因为整个系统已经被分解为若干个相对独立的子系统。

五层协议的体系结构

​ OSI的七层协议体系结构的概念清楚,理论也较完整,但它即复杂又不实用。TCP/IP体系结构则不同,它现在得到了非常广泛的应用。TCP/IP是一个四层的体系结构,从实质上讲,TCP/IP只有最上面三层,因为最下面的网络接口层(链路层)并没有属于TCP/IP体 系的具体协议,而是各种局域网标准。在学习时综合OSI和TCP/IP的优点,采用五层协议的体系结构,这对阐述计算机网络的原理是十分方便的。

image-20241125134910666

​ 简要的介绍一下各层的主要功能。

  • 应用层

    应用层的任务是通过应用进程间的交互来完成特定网络应用。应用层协议定义的是应用进程间通信和交互的规则。互联网中的应用层协议有很多,如域名系统DNS、支持万维网的HTTP、支持电子邮件的SMTP等。应用层交互的数据单元称为报文。

  • 运输层

    运输层的任务是负责向两台主机中进程之间的通信提供通用的数据传输服务。运输层主要使用以下两种协议:

    • 传输控制协议TCP(Transmission Control Protocol),提供面向连接的、可靠的数据传输服务,其传输数据的单位是报文段。
    • 用户数据报协议UDP(User Datagram Protocol),提供无连接的尽最大努力的数据传输服务,其数据传输的单位是用户数据报。
  • 网络层

    网络层负责为分组交换网上的不同的主机提供通信服务。在发送数据时,网络层把运输层产生的报文段或用户数据报封装成分组(IP数据报)或包进行传送。

  • 数据链路层

    两台主机之间的数据传输,总是在一段一段的链路上传送,在两个相邻节点之间传输数据时,数据链路层将网络层交下来的IP数据报组装成帧,两个相邻节点间的链路上传送帧。每一帧包括数据和必要的控制信息。

  • 物理层

    物理层上所传数据的单位是比特。

​ 数据在各层之间的传递过程如下:

image-20241125135059158

物理层

​ 物理层的主要任务为确定与传输媒体的接口有关的一些特性,如机械特性、电气特性、功能特性、过程特性等。

​ 数据在计算机内部多采用并行传输方式。但数据在通信线路上的传输方式一般都是串行传输,因此物理层还需要完成传输方式的转换。

  • 网卡(适配器)

    计算机与外界局域网的连接是通过适配器网卡,适配器的一个重要功能是要进行数据串行传输和并行传输之间的转换,以及对数据进 行缓存(解决网络和计算机传输速率不一致的问题)。

数据链路层

数据链路层的三个基本问题

  • 封装成帧

    封装成帧就是在一段数据的前后分别添加首部和尾部,这样据构成了一个帧。首部和尾部的一个重要作用就是进行帧定界。

  • 透明传输

    由于帧的开始和结束的标记使用专门指明的控制字符,因此,所传输的数据中任何8比特的组合一定不允许和用作帧定界的控制字 符的比特编码一样,否则就会出现帧定界错误。采用字节填充或字符填充的方式进行转义。

  • 差错检测

    比特在传输过程中可能会产生差错,为了保证数据传输的可靠性(并不等同于运输层的可靠传输),必须采用各种差错检测措施,目前在数据链路层广泛使用了循环冗余校验CRC的检错技术。数据链路层若仅仅使用CRC,则只能做到对帧的无差错接受,但要实现可靠传输,需要加上确认、帧编号、重传机制。

以太网

  • MAC地址

    MAC地址也叫硬件地址或物理地址,是长度为48位的全球地址,被固化到适配器的ROM中,用于在网络中唯一标识一个网卡。

网络层

​ 网络层向其上层提供简单灵活的、无连接的、尽最大努力交付的数据报服务,不提供服务质量的承诺。

网际协议IP

​ 与IP协议配套使用的还有地址解析协议ARP、网际控制报文协议ICMP、网际组管理协议IGMP。

  • IP地址

    IP地址就是给连接到互联网上的每一台主机的每一个接口分配一个在全世界范围内是唯一的32位的标识符。IP地址由两个字段组成,第一个字段是网络号,它标志主机所在的网络,第二个字段是主机号,它标志该主机。

  • 分类的IP地址

    在互联网早期采用的是分类的IP地址,每个网络中网络号全零的表示本网络,全一的为广播地址。

image-20241125135445234

  • 无分类编址CIDR

    CIDR把网络号改称为网络前缀,用来指明网络,使用斜线记法在IP地址后面加上斜线,斜线后面是网络前缀所占位数,把网络前缀都相同的所有连续IP地址组成一个CIDR地址块。一个CIDR地址块的IP地址数目取决于网络前缀所在位数。

    地址掩码也称为子网掩码,由一连串的1个接着一连串的0组成,1的个数为网络前缀的位数,把IP地址与子网掩码进行按位与运算即可得到网络地址。

  • IP数据报的格式

    以太网的最大传输单元MTU为1500字节,当IP数据包大小大于MTU时,IP数据包就会被分片,由目标主机进行重组,在分片传输过程中,一旦某个分片丢失,则会造成整个IP数据报作废。

​ 首部校验和只校验首部不校验数据部分。

image-20241125135523723

地址解析协议ARP

​ 地址解析协议ARP用于从IP地址找出其相应的MAC地址。在主机中的ARP高速缓存中存放IP地址到MAC地址的映射表,主机之间通过发送ARP分组,对映射表进行动态更新。

网际控制报文协议ICMP

​ 使用ICMP报告差错情况和提供有关异常情况的报告。

IP多播

​ 多播数据报和一般的IP数据报的区别是使用D类地址作为目的地址,目的地址为多播组的标识符,通过IGMP协议让本地局域网的多播路由器知道主机加入或退出某个多播组,多播路由器之间协同工作实现IP多播。

虚拟专用网VPN和网络地址转换NAT(TODO)

运输层

​ 网络层提供主机之间的通信服务,运输层在网络层的基础上为应用进程之间的通信提供服务。根据应用程序的不同需求,运输层需要有两种不同的运输协议,即面向连接的TCP和无连接的UDP。

TCP

​ TCP提供面向连接的服务。在传送数据之前必须建立连接,数据传送结束后要释放连接。TCP不提供广播或多播服务。由于TCP要提 供可靠的、面向连接的运输服务,因此不可避免地增加了许多的开销。

​ TCP的主要特点:

  • 面向连接

    TCP连接的端点叫套接字socket,为IP地址:端口号,每一条TCP连接唯一的被通信两端的两个端点所确定。

  • TCP连接只能有两个端点,只能是一对一的。

  • 提供可靠交付

  • 提供全双工通信

  • 面向字节流

    TCP把应用层交下来的数据仅仅看成是一连串无结构的字节流,不保证接收方应用程序所收到的数据块和发送方应用程序所发出的数据块具有相同的大小关系。TCP根据接收方的窗口值和当前网络拥塞的程度来决定一个报文段应包含多少个字节。如果应用进程传送到TCP缓存的数据块太长,就会划分为短一些的数据块再传送,如果应用进程发来的数据块太短,可等累计足够后再发送。

    当两个消息的某一部分内容被分到了同一个TCP报文时,就产生了粘包问题,如果接收方不知道消息边界的话,就无法读出有效数据,要解决这个问题,需要应用程序解决。

    粘包问题的解决方案:粘包问题的出现是无法确定消息边界,可以通过固定消息长度、特殊字符作为边界(HTTP报文)、自定义消息结构等方式解决粘包问题。

报文格式

image-20241125135704408

​ 序号:从[0, 2^32 - 1]循环使用,在TCP连接中传送的字节流的每一个字节都按顺序编号,首部中序号为所发送数据的第一个字节的序号,连接建立时取随机初始值。

​ 确认号:期望收到对方下一个报文段的第一个数据字节的序号。

​ 发送方发送数据长度200字节,序号501的报文,接收方正确收到该数据,返回的确认中确认号为701,有累计确认机制。

​ 数据偏移:实际上是指出TCP报文首部的长度。

​ URG(紧急):URG=1时表示是紧急数据,配合紧急指针使用。

​ ACK(确认):当ACK=1时确认号才有效。

​ PSH(推送):PSH=1时接收方收到报文后立即向上交付,而不是等到缓存填满。

​ RST(复位):RST=1时表示TCP连接出现严重错误。

​ SYN(同步):SYN=1表示是连接请求(ACK=0)或连接接受(ACK=1)报文。

​ FIN(终止):用来释放连接。

​ 窗口:[0, 2^16 - 1]之间,指的是该报文段发送方的接收窗口。

​ 选项:长度可变,配合填充字段保证TCP报文首部长度是4字节的整数倍。最大报文长度MSS、窗口扩大、时间戳、选择确认等。

连接建立

image-20241125135755230

​ 第三次握手可以防止失效的连接请求报文,如只采用两次握手,若客户端发出的第一个连接请求报文段在某些网络节点滞留了,而后 重传第二次连接请求报文成功建立连接,传输完毕连接关闭,而后原先第一次请求报文到达服务端,这时服务端会误认为是新的连接请 求,向客户端发出确认报文后就建立连接了,如采用三次握手,第三次服务端收不到客户端的确认报文从而无法建立连接。

​ 第三次握手是可以传输数据的,第二次握手之后就同步序列号了。

滑动窗口

​ TCP滑动窗口是以字节为单位的。

image-20241125135812841

​ 发送方的发送窗口表示在没有收到接收方确认的情况下,可以连续把窗口内的数据都发送出去。凡是以及发送过的数据,在接收方未 确认之前都必须进行暂时保留,以便重传时使用。发送方的发送窗口不得大于接收放的接收窗口,同时窗口大小还要受到拥塞控制的约束。

​ 接收方未收到序号为31的数据,只能返回确认号31(确认号表示期望受到的下一个报文段的第一个数据字节的序号)。

  • 超时重传

    TCP有超时重传的机制,超时重传时间设置的过大会使网络空闲时间增大,降低传输效率,设置的过小会导致很多报文段重传,增大网路负载。TCP采用了自适应算法,它记录了一个报文的往返时间RTT,计算加权平均往返时间RTTs,超时重传时间RTO=RTTs + 4 * RTTd,其中RTTd是RTT的偏差加权平均值。

  • 流量控制

    流量控制是让发送方的发送速率不要太快,要让接收方来得及接收,通过滑动窗口机制能够很方便的实现流量控制,发送放的发送窗口不得大于接收方的接收窗口。

    当接收方的接收窗口为0时有持续计时器机制,发送0窗口探测报文,避免死锁。

​ 队头阻塞问题:TCP必序按序处理数据,即使已经收到34~40字节的数据,由于第32字节没有收到,接收窗口无法向前滑动,已经收到的乱序的数据无法被应用层读取到。

拥塞控制

​ 若对网络中某一种资源的需求超过了该资源所能提供的可用部分,网络的性能就会变坏。这种情况就叫做拥塞。

​ 拥塞控制是防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不至于过载。拥塞控制是一个全局性的过程,涉及所有主机、路由器。

​ TCP中的拥塞控制

  • 慢开始和拥塞避免

    发送方维持一个拥塞窗口cwnd,让自己的发送窗口等于拥塞窗口,慢开始由小到大逐渐增大注入到网络中的数据字节,由小到大逐渐增加拥塞窗口,拥塞窗口的初始值为1至2个发送方的最大报文段MSS,在每收到一个新的报文段的确认后可以将拥塞窗口增加最多一个MSS。增加到慢开始门限时,执行拥塞避免算法,进行加法增大。

  • 快重传和快恢复

    快重传可以让发送方尽早知道发生了个别报文的丢失,接收方受到报文段时,立即发送确认而不进行捎带确认,即使收到了失序的报文段也要立即发出对已接收到的报文段的重复确认,当发送方收到三个重复确认时,就知道并未出现网络拥塞而是接收方缺失了报文段,因此立刻进行快重传,然后执行快恢复。

image-20241125135947656

​ 发生超时,执行慢开始,慢开始门限变为拥塞窗口的一半,拥塞窗口重置。

image-20241125135951153

​ 发生丢失,进行快恢复,慢开始门限变为拥塞窗口的一半,拥塞窗口变为原来的一半(乘法减小)。

​ 主动队列管理AQM

  • 网络层的策略对TCP拥塞控制最大的影响是路由器的分组丢弃策略,路由器的队列通常是先进先出的规则,由于队列长度是有限的,当队列已满时后面的分组将被丢弃,这就是尾部丢弃策略,在网络中通常有很多TCP连接,若发生了路由器中的尾部丢弃,可能会同时影响到很多条TCP连接,结果使很多条TCP连接在同一时间突然进入到慢开始状态,称为全局同步。

​ 为了避免全局同步现象,提出了主动队列管理,主动体现在不要等路由器队列长度满了才不得不丢弃分组,而是当路由器队列长度到达某个值得警惕的数值时主动随机丢弃一部分分组,使慢开始只在个别TCP连接上进行。

连接释放

image-20241125140046377

​ 客户端在计时等待(TIME-WAIT)时等待2MSL(最长报文段寿命)的原因:

  • 为了保证客户端发送的最后一个ACK报文段能够到达服务端,如服务端没有收到客户端发送的最后一个ACK报文段会进行超时重传,服务端能在2MSL时间内收到重传的报文段,然后重置2MSL计时器。

  • 防止失效的连接请求报文,经过2MSL时间后,本链接持续的时间内所产生的所有报文都从网络中消失了,可使下一个新的连接中不会出现这种旧的连接请求报文。

​ TCP还设有一个保活计时器,每收到一次数据保活计时器就重置,保活计时器到时间后会发出探测报文,每隔75秒发送一次,若10个探测报文均无响应,则认为对方故障,关闭连接。

​ 如何关闭TCP连接:

  • killcx:伪造一个四元组相同的 SYN 报文,来拿到“合法”的序列号,服务端收到四元组相同的 SYN 报文后会回复一个Challenge ACK,这个ACK报文里的确认号,就是服务端下一次想要接收的序列号,然后用这个确认号作为RST报文的序号发送给服务端,此时服务端会认为RST报文是合法的,于是释放连接。

  • tcpkill:在双进行TCP通信时,拿到对方下一次期望收到的序列号,然后伪造RST报文。

  • tcpkill只适用于关闭活跃的在传输数据的TCP连接,killcx不活跃的TCP连接也可以关闭。

UDP

​ UDP在传送数据之前不需要先建立连接。远程主机的运输层在收到UDP报文后,不需要给出任何确认。由于非常简单,在某些情况下UDP是一种最有效的工作方式。

​ UDP只在IP的基础上增加了少量功能:复用、分用、差错检测。

​ UDP的主要特点:

  • 无连接

  • 尽最大努力交付

  • 面向报文

    发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付IP层。UDP对应用层交下来的报文,即不合并,也不拆分。若报文太长,UDP把它交给网络层后,IP在传输时可能要进行分片。

  • 没有拥塞控制

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

​ UDP的报文格式:

  • 其中伪首部的主要目的是为了计算校验和,通过伪首部,可以确保数据包的完整性和准确性,防止数据在传输过程中被篡改或损坏。

image-20241125140247597

应用层

DNS域名系统

​ DNS能把互联网上的主机名转换为IP地址,DNS域名系统被设计成一个联机分布式数据库系统,DNS大多数名字都在本地进行解析,仅少量解析需要在互联网上。

​ 使用UDP传输。

HTTP

​ 统一资源定位符URL,协议://主机名:端口/路径,HTTP端口默认80。

​ HTTP超文本传输协议,是一个应用层协议,它使用TCP连接进行可靠传输。

image-20241125140317455

HTTP如何解决TCP粘包问题

​ HTTP通过设置回车、换行符作为HTTP Header的边界,通过Content Length字段作为HTTP Body的边界解决粘包问题。当消息包含特殊字符时需要进行转义。

image-20241125140329884

HTTP版本变化

​ HTTP/1.1版本的连接默认都是长连接、支持管道,客户端可以同时发出多个请求,但服务端只能按请求的顺序进行响应,存在HTTP层面响应队头阻塞问题。

​ HTTP/2版本基于HTTPS,安全性有保障、且支持头部压缩、二进制格式数据、并发传输,但发生丢包会阻塞所有HTTP请求,存在TCP层面队头阻塞问题。

​ HTTP/3版本使用QUIC协议,基于UDP,且解决了队头阻塞问题。

网络安全

HTTPS

​ HTTP是超文本传输协议,信息是明文传输,存在安全风险的问题。HTTPS则解决HTTP不安全的缺陷,加入了SSL/TLS安全协议,使得报文能够加密传输。TCP三次握手之后还需进行SSL/TLS四次握手,HTTPS需要向CA申请数字证书来保证服务器的身份是可信的。

​ 窃听风险:信息加密,采用混合加密方式,使用非对称加密交换会话密钥,通信过程中使用对称加密

​ 篡改风险:校验机制,通过摘要算法生成哈希值防止数据被修改,使用私钥对哈希值加密进行数字签名

​ 冒充风险:身份证书

​ SSL/TLS协议基本流程:

  • Client Hello

    由客户端向服务端发起加密通信请求,客户端需要向服务端发送自己支持的TLS版本、随机数Client Random(用于生成会话密钥)、支持的密码套件。

  • Server Hello

    服务端收到客户端请求后发出响应,内容包含确认TLS版本、随机数Server Random、确认密码套件、数字证书。

  • 客户端回应

    客户端收到服务端回应后,通过浏览器或操作系统中的CA公钥,确认服务端的证书真实性,如果真实会从证书中取出服务端的公钥,然后用它加密报文,报文内容为随机数Pre Master Key、加密通信算法改变通知,表示随后的信息用会话密钥加密通信、客户端握手结束通知。

​ 三次握手之后,通过三个随机数和确定的加密套件,生成本次通信的会话密钥。

image-20241125140446166

  • 服务端的最后回应

    收到客户端的消息后向客户端返回加密通信算法改变通知、服务端握手结束通知。

​ 目前常用的密钥加密算法有RSA和ECDHE

  • RSA算法存在向前安全问题,如果服务端的私钥泄露了,则所有的TLS通讯密文都会被破解。

其他

Linux内核TCP半连接队列与全连接队列

​ 在TCP三次握手的时候,Linux内核会维护两个队列,分别是:

  • 半连接队列,也称SYN队列

  • 全连接队列,也称accept队列

​ 服务端收到客户端发起的SYN请求后,内核会把该连接存储到半连接池,并向客户端响应SYN+ACK报文,接着客户端会返回ACK报文,服务端收到后会把连接从半连接队列中移除,然后创建新的完全连接,并将其添加到全连接队列,等待进程调用accept函数把连接 取出。

​ 不管是半连接队列还是全连接队列,都有最大长度的限制,当超出限制时,内核会直接丢弃,或返回RST包。

​ SYN攻击是攻击服务端的半连接队列。

如何基于UDP实现可靠传输(QUIC)

​ 要基于UDP实现可靠传输,需要在应用层实现。

image-20241125140533483

​ QUIC协议也需要三次握手来建立连接,主要为了协商连接ID,后续传输时,双方只需要固定连接ID,即可实现连接迁移(利于移动设备)。

image-20241125140557596

​ Packet Header在首次建立连接时和传输数据时是不一样的(上图只画出了Header部分字段)。

​ QUIC协议的序列号是严格递增的,当发送超时重传时,序列号并不相同,避免重传歧义,更精确计算RTT,同时让数据包不像TCP 那样必须有序确认,QUIC支持乱序确认,只要有新的已接收数据包的确认,当前窗口就会继续滑动,解决了队头阻塞问题(宏观上并 不是所有的Stream都发生了队头阻塞)。

​ 一个Packet报文可以存放多个QUIC Frame。每一个 Frame 都有明确的类型,针对类型的不同,功能也不同,自然格式也不同。

​ Stream 类型的 Frame 格式如下:

image-20241125140607812

​ Stream ID:多个并发传输的HTTP消息,通过不同的Stream ID进行区分。

​ Offset:类似于TCP协议中Seq序号,保证数据的顺序性和可靠性。

​ Length:指明了数据的长度。

QUIC解决可靠传输

​ 通过Stream ID + Offset实现数据的有序性,丢失的数据包和重传的数据包的Stream ID和Offset都一样。

QUIC解决队头阻塞(多路复用机制)

​ QUIC借鉴了HTTP/2里Stream的概念,在一条QUIC连接上可以并发发送多个HTTP请求(Stream)。但是QUIC给每个Stream都分配了一个独立的滑动窗口,这样使得一个连接上的多个Stream之间相互独立,各自控制滑动窗口。

QUIC流量控制

​ QUIC每个Stream都有各自的滑动窗口,支持Stream级别的流量控制和连接级别的流量控制,连接级别的流量控制限制每一个Stream可用窗口大小之和。

QUIC拥塞控制

​ QUIC当前默认使用了TCP的Cubic拥塞控制算法(慢开始、拥塞避免、快重传、快恢复),同时还支持其他拥塞控制算法,由于QUIC属于应用层,可以针对不同的应用设置不同的拥塞控制算法,灵活性高。

用了TCP协议,数据一定不会丢失吗

​ TCP保证的可靠性,是传输层的可靠性,接收端TCP缓冲区成功接收到消息后返回ACK,发送端收到ACK之后会将自己发送缓冲区 里的消息丢掉。应用软件还需要从TCP缓冲区里读数据,过程中软件崩溃则数据就丢失了。

​ 想要保证应用层的可靠性需要自己实现逻辑。

部分内容转载自小林coding