计算机网络学习笔记2025
本文摘要:计算机网络学习笔记第一章概述了计网基础概念,包括协议三要素(语法、语义、同步)和网络结构划分(边缘与核心)。重点对比了电路交换(独占资源)和分组交换(资源共享)的特性及适用场景,分析了ISP层级结构和四种分组延迟类型(处理/排队/传输/传播)。第二章应用层部分阐述了网络应用体系结构(C/S、P2P)及套接字作为进程通信接口的核心作用,简要提及常见安全威胁(DoS、中间人攻击等)。全文以技
计算机网络学习笔记–寒枫
第一章 计网概论
计网定义:两台以上具有独立操作系统的计算机通过某些介质连接成的相互共享软硬件资源的集合体。最重要的功能:连通、共享。
Internet:提供网络应用基础架构,为分布式应用程序提供的通信服务接口。标准文档:RFC。
1.1协议
协议(Protocol) 是计算机网络中为实现数据交换和通信协同而制定的规则、标准或约定的集合。它规定了通信双方在数据传输过程中的格式、时序、语义和同步方式,确保不同设备或系统间能准确、高效地交互。
功能:控制发送和接收消息。 实例:TCP, IP, HTTP, FTP, SMTP。
协议的三要素: 语法、语义、同步(时序)
1.2 网络边缘
边缘:客户机和服务器。通路:有线或者无线通信链路。
接入网络
将终端系统连接到网络边缘的路由器
1、家庭接入:点对点接入,cable modems线缆调制解调器,FTTH(Fiber To The Home)-光纤到户
2、企业接入:local area networks (LAN)
3、WiFi无线接入网络
4、 广域无线接入网络
物理介质
双绞线:两根彼此绝缘、相互缠绕成螺旋状的铜线。减少电磁干扰,提高传输质量。
同轴电缆和光纤线缆
无线电磁波
端系统上的因特网服务
1、面向连接的服务:TCP服务(HTTP、FTP、SMTP)
2、无连接服务:UDP服务(流媒体、视频会议、DNS、网络电话)
1.3 网络核心
核心:相互连接的路由器构成的网络。
传输基本原理:
电路交换(Circuit Switching)
核心定义:在通信过程中,为用户会话预留从源到目的路径上的独占物理资源,形成固定通信链路。
(一)关键特性
- 资源分配模式
- 独占性:一旦建立连接,路径上的带宽、信道等资源完全分配给该会话,未使用时处于空载状态(不共享)。
- 性能保证:由于资源固定,通信延迟和带宽稳定性高,适合实时业务(如传统电话网络)。
- 分片实现方式
- FDMA(频分多址):将频段划分为多个子频段,每个会话占用固定频段(如早期电话网的频分复用)。
- TDMA(时分多址):将时间划分为时间片,每个会话周期性占用固定时间片(如GSM移动通信)。
- 通信流程
- 三阶段:建立连接 → 数据传输 → 释放连接(如电话拨号的过程)。
分组交换(Packet Switching)
核心定义:将数据分割为离散分组(Packet),通过网络节点转发,共享网络资源。
(一)核心机制
- 分组化传输
- 数据分割:端到端数据流被拆分为多个带头部(含地址信息)的分组。
- 资源共享:分组按需使用链路带宽,不固定占用资源(如互联网数据传输)。
- 转发模式:存储转发(Store-and-Forward)
- 节点处理:每个节点接收完整分组后,检查地址再转发至下一跳。
- 优势:适配不同链路带宽,容错性强(分组可重传),但引入转发延迟。
(二)分组交换类型对比
数据报网络: TCP/IP,分组目的地址决定下一跳,会话期间路由可以改变
虚电路网络: X.25,FR,ATM,每个分组有1个标签 (虚电路号,virtual circuit ID), 标签决定下1跳。连接建立时确定固定的路径, 并且将保持于整个会话期间。路由器必须为每个连接维护状态信息。
| 类型 | 数据报网络(Datagram) | 虚电路网络(Virtual Circuit) |
|---|---|---|
| 典型案例 | TCP/IP(互联网)、UDP | X.25、FR(帧中继)、ATM(异步传输模式) |
| 路由机制 | 每个分组独立根据目的地址决定下一跳 | 连接建立时确定固定路径,全程保持不变 |
| 状态维护 | 路由器无需维护会话状态,会话期间路由可以变化 | 路由器需为每个连接维护虚电路表(标签映射) |
| 标签标识 | 无标签,依赖IP地址 | 分组携带虚电路号(VCID)作为转发依据 |
(三)资源竞争与拥塞控制
-
队列机制:当链路繁忙(拥塞)时,分组进入缓冲区排队,等待转发(可能导致延迟或丢包)。 适应场景:突发数据传输(如网页浏览、文件下载),允许多用户共享网络,但性能受负载影响。
存储转发: 分组每次转发1站,在1个链路上传输,每经过1个链路转发1次,转发分组前,要求收到完整分组。适用于对数据完整性要求高的场景(如文件传输、电子邮件),通过校验和重传机制减少错误。但延迟增加。
(四)与电路交换的性能对比
- 优势:资源利用率高(按需分配),支持大量用户并发。
- 劣势:无固定带宽保证,网络拥塞时延迟波动大。
1.4 ISP的结构组成
ISP(Internet Service Provider)即互联网服务提供商
1.5 延迟、丢失和吞吐量
延迟的原因:分组在路由器分组缓冲区队列排队, 按序等待
分组延迟的4种类型:
节点处理时延(检查错误位、选择输出链路),排队时延(等待被发送到输出链路上的时间 ,取决于路由器的拥塞程度),传输时延(发送分组比特流的时间 = 分组长度L/链路带宽R),传播时延(传播延迟 = 物理链路长度d/介质信号传播速度s)
分组丢失:分组到达输出链路的速率超过输出链路的容量,产生丢失,丢失的分组可能被前路由节点、源节点重传,或不重传。
吞吐量:接收端接收到数据的比特速率 (bps)。吞吐量瓶颈具有短板效应。
1.6 协议层及其服务模型
分层使得系统简化,更容易维护。
| 层次 | 核心功能 | 具体职责 | 常见协议/技术 |
|---|---|---|---|
| 应用层 | 直接为用户应用程序提供服务,是用户与网络交互的接口 | 处理特定应用协议(数据格式、交互逻辑) 提供文件传输、电子邮件、网页浏览等服务 | HTTP、HTTPS、FTP、SMTP、POP3、DNS、Telnet |
| 传输层 | 为端到端(进程间)通信提供服务,屏蔽底层网络细节 | 建立/维护/终止逻辑连接(如TCP连接) 实现流量控制、差错控制、数据分段重组 通过端口号标识应用进程(如HTTP默认80端口) | TCP、UDP |
| 网络层 | 负责网络间的数据路由与寻址,实现跨网络通信 | 通过IP地址标识设备,完成路由选择 处理分组分片与重组(适应MTU限制) 实现异构网络互联(如局域网与广域网) | IP(IPv4/IPv6)、ICMP、ARP、RIP、OSPF |
| 链路层 | 在相邻节点间传输数据,确保物理链路可靠传输 | 将IP分组封装为帧(添加MAC地址、校验信息) 实现介质访问控制(如CSMA/CD) 处理差错检测(CRC校验)和流量控制 | Ethernet(以太网)、PPP、HDLC、802.11(WiFi链路层) |
| 物理层 | 网络模型最底层,直接与物理介质交互 | 定义物理设备接口标准(电缆类型、引脚功能) 实现比特流传输,处理信号编码/调制 规定传输速率和信号传输方式(单工/全双工) | RJ-45接口、光纤接口、IEEE 802.3(以太网物理层)、调制解调技术 |
1.7 攻击威胁
-
植入恶意软件:病毒、蠕虫、僵尸网络
-
攻击服务器和网络基础设施:拒绝服务攻击(DoS);三种类型:弱点攻击,带宽洪泛,连接洪泛
-
嗅探分组:分组嗅探器:记录每个流经的分组拷贝的被动接收机;容易受到攻击的网络:无线网络和以太网LAN
-
伪装:将具有虚假源地址的分组注入因特网
-
修改或删除报文:中间人攻击
第二章 应用层
2.1 应用层协议原理
网络应用程序体系结构
三种:客户机/服务器体系结构,P2P体系结构,混合
服务器:总是打开的主机,具有固定的、众所周知的IP地址,主机群集常被用于创建强大的虚拟服务器
客户机:同服务器端通信,可以间断的同服务器连接,可以拥有动态IP地址,客户机相互之间不直接通信
P2P:没有总是打开的服务器,任意一对主机直接相互通信,对等方间歇连接(仅在主动发起请求或提供资源时保持连接)并且可以改变IP地址,比如Gnutella
进程通信:同一主机上的两个进程通过内部进程通信机制进行通信,不同主机上的进程通过交换报文相互通信
进程与计算机网络的接口-套接字
套接字(Socket)的核心定义与角色
-
套接字是应用层与传输层之间的接口,类比为进程间通信的“门户”:
- 发送进程通过套接字将报文“推出”到网络,接收进程通过套接字“接入”报文。
- 套接字屏蔽了底层网络传输细节(如链路传输、路由选择),进程只需关注数据的发送与接收。
-
套接字是操作系统提供的网络编程接口,用户通过API可控制:
- 传输协议选择:如TCP(可靠连接)或UDP(无连接)。
- 参数配置:如超时时间、缓冲区大小等(不同协议可配置参数不同)。
套接字的通信模型与工作机制
1. 进程标识与寻址
-
网络中唯一标识进程需组合:
- 主机IP地址:定位网络中的目标主机。
- 端口号(Port Number):标识主机上的具体进程(16位无符号整数,范围0~65535)。
-
常见服务端口示例:
服务类型 端口号 协议 Web服务(HTTP) 80 TCP 邮件服务(SMTP) 25 TCP 域名解析(DNS) 53 UDP
2. 数据传输流程类比
-
发送进程视角:
应用层数据 → 套接字(门户)→ [底层网络设施(如TCP/UDP协议)] → 目标套接字 (推送报文) (假定运输设施存在) (接收报文) -
关键抽象:进程无需关心“门户到另一侧”的具体传输细节(如报文如何路由、是否重传),仅需通过套接字接口操作。
套接字的类型与应用场景
1. 基于传输协议的分类
- 流式套接字(SOCK_STREAM):
- 基于TCP协议,提供面向连接的可靠传输(保证顺序、无丢失、无重复)。
- 适用场景:文件传输(FTP)、网页浏览(HTTP)。
- 数据报套接字(SOCK_DGRAM):
- 基于UDP协议,提供无连接的不可靠传输(低延迟,不保证可靠性)。
- 适用场景:实时视频(RTSP)、网络语音(VoIP)。
2. 套接字地址结构(Socket Address)
- 在TCP/IP中,套接字地址由IP地址+端口号组成,称为“套接字对”(Socket Pair),例如:
(192.168.1.1:80)。
TCP:
面向连接的服务:在客户机程序和服务器程序之间必须建立连接;可靠的传输服务: 接收和发送进程间;
流量控制: 发送方不会淹没接收方;拥塞控制: 网络出现拥塞时抑制发送进程; 没有提供:时延保证,最小带宽保证
UDP:不可靠数据传输。没有提供:建立连接,可靠性,流量控制,拥塞控制,时延和带宽保证
2.2 Web应用和HTTP协议
使用TCP:
客户初始化一个与HTTP服务器80端口的TCP连接 (创建套接字),HTTP服务器接受来自客户的TCP连接请求, 建立连接,Browser (HTTP client)和Web服务器 (HTTP server) 交换HTTP消息(应用层协议消息)包括HTTP请求和响应消息,最后结束(或叫关闭)TCP连接
HTTP是无状态协议:HTTP服务器不维护客户先前的状态信息。
HTTP的发展
定义往返时间RTT(Round-Trip Time): 1个小分组从客户主机到服务器再到客户主机所花费的时间
HTTP/1.0响应时间: total = 2RTT+transmit time
1个RTT用于建立TCP连接,1个RTT用于HTTP请求/响应消息的交互,html文件传输时间
HTTP/1.1是持久连接:一个TCP连接上可以传送多个对象
HTTP/2:对象被划分为帧(frame),帧交错传输,减少多对象HTTP请求的延迟 ,但仍通过单个TCP连接
HTTP/3:通过UDP增加了安全性、每个对象的错误和拥塞控制
HTTP报文格式
请求报文:
响应报文:
Cookies:跟踪用户
- 定义:Cookies 是由 Web 服务器存储在用户浏览器中的小型文本文件,用于跟踪用户行为和状态。
- 作用:
- 记录用户登录信息、偏好设置(如语言、主题)、购物车内容等,实现“状态保持”。
- 帮助网站分析用户行为(如访问频率、页面浏览路径),用于个性化推荐或广告投放。
- 工作原理:
- 服务器返回响应时,通过
Set-Cookie头部将 Cookies 存入浏览器。 - 后续浏览器向同一服务器发送请求时,自动携带 Cookies,服务器通过解析 Cookies 识别用户。
- 服务器返回响应时,通过
Web 缓存(代理服务器)
- 定义:Web 缓存是存储 Web 资源(如网页、图片、视频)的中间服务器(代理服务器),用于减少重复请求的网络延迟。
- 核心作用:
- 提高访问速度:用户请求资源时,若缓存中存在副本,直接返回缓存数据,避免重复从源服务器获取。
- 减轻服务器负载:减少源服务器的请求次数,降低带宽消耗。
- 典型场景: 企业内部通过代理服务器缓存常用网站资源,提升员工访问速度。 运营商部署公共缓存服务器,优化区域网络性能。
条件 GET 方法
- 定义:HTTP 协议中的
GET请求扩展方式,用于判断缓存资源是否需要更新,避免重复传输完整数据。 - 工作原理:
- 浏览器首次请求资源时,服务器返回资源并附带缓存标识(如
Last-Modified时间、ETag哈希值)。 - 后续请求时,浏览器通过
If-Modified-Since或If-None-Match头部携带缓存标识,询问服务器资源是否更新。 - 若资源未更新,服务器返回
304 Not Modified,浏览器使用本地缓存;若更新,则返回新资源(200 OK)。
- 浏览器首次请求资源时,服务器返回资源并附带缓存标识(如
- 优势:减少网络传输量,提升缓存效率,降低带宽消耗。
2.3 文件传输协议:FTP(选学)
核心架构与连接机制
FTP采用双连接机制(区别于HTTP等单连接协议):
- 控制连接(Control Connection)
- 端口:默认使用TCP端口 21(始终开启,用于传输命令和响应)。
- 功能:客户端与服务器建立长期连接,传输FTP命令(如登录、列表查询、文件操作指令等)。
- 特点:基于文本交互,命令和响应均为ASCII格式(如
USER、PASS、LIST、RETR等)。
- 数据连接(Data Connection)
- 端口:由传输模式决定(主动模式或被动模式)。
- 功能:临时建立,仅用于传输文件数据或目录列表,传输完成后关闭。
- 两种模式:
- 主动模式(Active Mode)
- 服务器主动连接客户端的数据端口(默认TCP端口 20)。
- 问题:可能被客户端防火墙拦截(需开放服务器到客户端的出站端口)。
- 被动模式(Passive Mode)
- 客户端主动连接服务器的临时端口(服务器通过
PASV命令告知客户端端口号)。 - 优势:适应复杂网络环境(如NAT、防火墙),现代应用更常用。
- 客户端主动连接服务器的临时端口(服务器通过
- 主动模式(Active Mode)
核心功能与操作流程
- 用户认证
- 支持明文认证(默认):客户端通过
USER和PASS命令发送用户名和密码。 - 可选匿名登录:用户名
anonymous,密码通常为邮箱地址(用于公开文件共享)。
- 支持明文认证(默认):客户端通过
- 文件传输操作
- 下载(Retrieve):客户端发送
RETR命令请求服务器传输文件。 - 上传(Store):客户端发送
STOR命令向服务器写入文件。 - 其他操作:目录浏览(
LIST/NLST)、文件删除(DELE)、重命名(RNFR/RNTO)等。
- 下载(Retrieve):客户端发送
- 传输类型与格式
- 文本模式(ASCII):用于传输文本文件(如
.txt),会自动转换换行符(如Windows的CRLF与Unix的LF互转)。 - 二进制模式(Binary):用于传输二进制文件(如
.zip、.exe),按字节原样传输,避免格式错乱。
- 文本模式(ASCII):用于传输文本文件(如
2.4 电子邮件SMTP,POP3,IMAP
电子邮件系统的三大核心组成部分
- 用户代理User Agents
-
定义:用户直接交互的软件或客户端,负责邮件的撰写、阅读、管理及与服务器的通信。
-
核心功能:
- 内容操作:支持撰写、编辑、回复、转发邮件,管理联系人列表。
- 存储与检索:将邮件存储在本地或服务器(如草稿箱、收件箱),提供搜索功能。
- 协议交互:通过邮件协议(如SMTP、POP3、IMAP)与服务器通信,发送/接收邮件。
-
典型示例:Gmail、Outlook.com、网易邮箱。
- 邮件服务器Mail Servers
- 定义:负责邮件传输、存储和分发的基础设施,是邮件系统的“中转站”。
- 分类及功能:
- 发送方邮件服务器(SMTP服务器):客户使用TCP来可靠传输邮件消息到服务器端口号25,通过SMTP协议将邮件传输至接收方服务器。传输的3个阶段:握手 (问候),邮件消息的传输,结束。SMTP使用持久连接,SMTP 要求邮件消息(header & body)必须是7-bit ASCII,SMTP服务器使用CRLF.CRLF 来判断邮件消息的结束
- 接收方邮件服务器(POP3/IMAP服务器):存储用户邮件,等待用户代理通过POP3或IMAP协议下载或同步。
- 关键特性:
- 可靠性:支持邮件队列机制,若传输失败可重试(如延迟发送)。
- 安全性:部署反垃圾邮件过滤、病毒扫描、加密传输(如TLS)等功能。
- 核心协议Mail Protocols
| 协议 | 功能 | 传输方向 | 连接方式 | 服务器存储 | 多设备同步 | 场景 | 端口 |
|---|---|---|---|---|---|---|---|
| SMTP | 发送/中转邮件 | 客户端→服务器 或 服务器→服务器 | TCP | 不存储邮件 | 不涉及 | 发件操作 | 25 |
| POP3 | 下载邮件 | 服务器→客户端 | TCP | 下载后默认删除 | 不支持 | 单机离线阅读 | 110 |
| IMAP | 管理/同步邮件 | 客户端↔服务器 | TCP | 保留服务器副本 | 支持 | 多设备实时协作 | 143 |
电子邮件的工作流程
- 撰写与发送阶段:
- 用户通过UA撰写邮件,UA调用SMTP协议连接发送方服务器(如smtp.163.com),将邮件内容传输至服务器。
- 传输与路由阶段:
- 发送方服务器根据收件人邮箱域名(如@example.com),通过DNS查询找到接收方服务器的MX(邮件交换)记录,建立SMTP连接并传输邮件。
- 若接收方服务器不可达,发送方服务器会暂存邮件并定期重试(通常持续数天)。
- 接收与存储阶段:
- 接收方服务器收到邮件后,将其存储在收件人的邮箱账户中,等待UA通过POP3或IMAP协议获取。
- 读取与管理阶段:
- 用户通过UA连接接收方服务器,使用POP3或IMAP协议下载或同步邮件。例如:
- POP3模式:邮件下载至本地后,服务器默认删除(适合单设备离线使用)。
- IMAP模式:邮件保留在服务器,支持多设备同步(如网页端与手机端同时查看更新)。
- 用户通过UA连接接收方服务器,使用POP3或IMAP协议下载或同步邮件。例如:
2.5 DNS(域名系统):因特网的目录服务
DNS定义与作用
DNS(Domain Name System,域名系统)是互联网的核心基础设施之一,本质上是一个存储资源记录(RR,Resource Records)的分布式数据库系统,用于将人类易读的域名解析为计算机可识别的IP地址。
四个基本功能
主机名到IP地址的转换。
主机别名:一个主机可以有一个规范主机名和多个主机别名
邮件服务器别名
负载分配:DNS实现冗余服务器,一个IP地址集合可以对应于同一个规范主机名
DNS工作原理
1. 域名结构与层级
域名采用层次化结构,由右至左分为多个层级:
- 根域名(
.):最高层级,全球仅13组根服务器(标识为A~M)。 - 顶级域名:如
.com、.org、.cn(国家/地区代码顶级域名,如.cn代表中国)。 - 二级域名:如
abc.com中的abc,由用户注册并管理。 - 子域名:如
mail.abc.com中的mail,用于区分同一域名下的不同服务。
2. 解析流程(递归查询与迭代查询)
当用户在浏览器输入域名时,DNS解析过程如下:
- 客户端查询本地DNS缓存:若存在记录,直接返回IP地址;否则进入下一步。
- 递归查询本地域名服务器(LDNS):
- LDNS向根域名服务器询问该域名的顶级域名服务器地址。
- 根服务器返回对应顶级域名服务器(如
.com服务器)的地址。 - LDNS向顶级域名服务器询问二级域名服务器(如
abc.com服务器)的地址。 - 二级域名服务器返回该域名对应的IP地址,LDNS缓存结果并返回给客户端。
整个过程**通过递归查询(名字解析的负担交给被查询的名字服务器)和迭代查询(问别的服务器)**结合完成,无需用户手动参与。
3. DNS记录类型
RR 格式: (name, value, type,ttl)
DNS通过不同类型的记录存储域名相关信息,常见类型包括:
| 记录类型 | 作用 | 示例 |
|---|---|---|
| A | 域名指向IPv4地址 | example.com A 192.0.2.1 |
| AAAA | 域名指向IPv6地址 | example.com AAAA 2001:db8::1 |
| MX | 指定邮件服务器地址(优先级由数字表示,数字越小优先级越高) | example.com MX 10 mail.example.com |
| CNAME | 别名记录,将一个域名指向另一个域名(常用于CDN或服务迁移) | cdn.example.com CNAME example.cloudflare.com |
| NS | 指定域名的权威名称服务器(用于 delegation 机制) | example.com NS ns1.example.com |
| TXT | 存储文本信息(常用于SPF、DKIM等邮件安全验证) | example.com TXT "v=spf1 mx -all" |
DNS报文
DNS的关键特性与技术
1. 分布式与冗余设计:DNS系统采用分布式架构,避免单点故障。
2. 缓存机制
- 各级DNS服务器和客户端会缓存解析结果,减少重复查询压力,提升访问速度。
- 缓存时间由
TTL(Time To Live)字段控制,单位为秒(如TTL 3600表示缓存1小时)。
3. DNS安全扩展(DNSSEC)
- 作用:防止DNS欺骗(DNS Spoofing)和数据篡改,通过数字签名验证解析结果的真实性。
- 原理:利用公钥密码学为域名记录添加签名,验证过程如下:
- 权威服务器对域名记录进行签名(如
example.com的A记录)。 - 递归服务器在解析时验证签名,确保记录未被篡改。
- 权威服务器对域名记录进行签名(如
4. 专用DNS服务
- 公共DNS:如Google DNS(8.8.8.8)、Cloudflare Warp(1.1.1.1),提供高速、安全的解析服务。
- 私有DNS:企业内部使用,用于解析私有域名(如
intranet.example),与公网隔离。
DNS面临的安全威胁
- DNS欺骗(DNS Spoofing):伪造解析结果,引导用户访问恶意网站。
- DNS缓存污染:篡改DNS服务器的缓存记录,导致错误解析。
- DDoS攻击:针对DNS服务器的分布式拒绝服务攻击,导致服务中断。
- 域名劫持:通过攻击域名注册商或DNS服务器,篡改域名指向。
实践 :nslookup
2.6 P2P技术(选学)
P2P的核心定义与本质
P2P(Peer-to-Peer,点对点技术)是一种去中心化的网络架构,其中每个节点(称为“对等节点”或“Peer”)既作为客户端请求服务,又作为服务器提供服务,无需依赖中心化服务器。其核心特点包括:
- 去中心化:无中心节点,所有Peer地位平等,资源分布存储于各节点。
- 自组织性:节点可动态加入或离开网络,自动发现和连接其他节点。
- 高扩展性:网络规模越大,可用资源和带宽越丰富(区别于传统C/S架构的服务器瓶颈)。
工作原理与架构分类
1. 经典架构类型
根据节点间协作方式,P2P可分为三类:
(1)集中式P2P
- 特点:存在目录服务器(如早期的Napster),用于存储节点索引信息(如文件位置)。
- 优缺点:
- 优点:查询效率高,类似传统C/S架构。
- 缺点:目录服务器易成为单点故障,且面临版权监管风险(如Napster被关停)。
(2)分布式非结构化P2P
- 特点:无中心服务器,节点通过洪泛(Flooding)**或**随机转发发现资源(如Gnutella、BitTorrent的DHT网络)。
- 关键技术:
- 洪泛查询:节点向相邻节点广播请求,逐步扩散至全网。
- Kademlia(KAD)协议:基于分布式哈希表(DHT)的节点定位算法,用于BitTorrent等场景。
(3)分布式结构化P2P
- 特点:通过**分布式哈希表(DHT, Distributed Hash Table)**结构化组织节点,资源存储位置可通过算法精确计算(如Chord、CAN、Pastry)。
- 优势:查询复杂度低(通常为对数级),支持大规模动态网络,适合需要高效定位的场景(如区块链、分布式存储)。
2. 核心工作流程(以文件共享为例)
- 节点加入网络:通过引导节点(Bootstrap Node)获取初始连接列表。
- 资源索引与发布:节点将本地文件哈希值、元数据等信息注册到DHT网络或目录服务器。
- 资源查询:
- 集中式:向目录服务器请求目标文件的节点列表。
- 分布式:通过DHT算法计算目标节点位置,或洪泛查询全网。
- 数据传输:节点直接建立连接,传输文件数据(如BitTorrent的分片下载)。
2.7 内容分发网络CDN
CDN的定义与核心目标
内容分发网络(Content Delivery Network,CDN) 是一种通过在全球各地部署分布式服务器(节点),将内容(如网页、图片、视频、文件等)缓存到离用户更近的位置,从而提高内容传输速度、降低延迟,并提升用户体验的网络架构。
两种部署原则
就近性原则:将内容缓存至离用户物理位置或网络路径最近的节点,降低延迟并提升访问速度
负载均衡原则:优化全网流量分配,避免单个节点过载,确保整体服务稳定性和资源利用率
CDN的关键组成部分
- 边缘节点(Edge Nodes)
- 分布在全球各地的缓存服务器,直接响应用户请求,存储热门内容的副本。
- 作用:就近提供内容,减少用户到源站的物理距离和传输路径。
- 中心服务器(源站,Origin Server)
- 存储内容的原始版本,当边缘节点无用户所需内容时,边缘节点会向源站请求获取。
- 负载均衡设备(Load Balancing)
- 包括DNS负载均衡和HTTP重定向,用于将用户请求分配到最优的边缘节点。
- 策略:根据用户IP地址、网络延迟、节点负载等因素,选择“最快”节点响应请求。
- 内容管理系统(CMS)
- 负责将源站内容分发到边缘节点,支持内容更新、缓存刷新等操作。
CDN的工作原理
- 用户请求流程
- 用户在浏览器输入网址(如
www.example.com),首先通过DNS解析获取CDN的全局负载均衡节点IP。 - 负载均衡节点根据用户位置、节点状态等,返回离用户最近的边缘节点IP。
- 用户向边缘节点发起请求:
- 若边缘节点有缓存内容,直接返回给用户(响应速度极快);
- 若没有,边缘节点向源站请求内容,缓存到本地后再返回给用户,并更新缓存。
- 用户在浏览器输入网址(如
- 内容分发流程
- 主动分发:源站通过CMS将内容预先推送到边缘节点(如热门视频上线前预缓存)。
- 被动分发:边缘节点在接收到用户请求时,按需从源站拉取内容并缓存(适用于低频访问内容)。
第三章 传输层
3.1 传输层服务
在两个不同的主机上运行的进程之间提供逻辑通信,是可靠,增强的的网络层服务。传输层协议运行在端系统。
发送方: 将应用程序报文分成数据段传递给网络层。
接受方: 将数据段重新组装成报文传递到应用层。
传输层的两大协议:TCP与UDP
传输层的核心功能
- 复用与分用(Multiplexing/Demultiplexing)
- 复用:传输层多个进程的数据可通过同一个传输层协议(如TCP/UDP)发送到网络层。
- 分用:传输层根据**端口号(Port Number)**将接收的数据准确交付给对应的进程。
- 端口号:
- 16位无符号整数(范围0~65535),标识应用进程(如HTTP默认端口80,HTTPS默认端口443)。
- 分为知名端口(Well-Known Ports,01023)**、**注册端口(102449151)、动态/私有端口(49152~65535)。
- 流量控制(Flow Control)
- 解决发送方与接收方速度不匹配的问题,避免接收方因缓冲区满而丢包。
- TCP通过滑动窗口协议实现流量控制,UDP无内置流量控制(需应用层自行处理)。
- 差错控制(Error Control)
- 检测并纠正传输过程中的错误(如数据 corruption、丢包)。
- TCP通过校验和(Checksum)、序列号、确认应答、重传机制实现可靠传输;UDP仅通过校验和检测错误,不重传。
- 连接管理(仅TCP)
- 负责建立、维护和释放端到端的连接,通过三次握手和四次挥手确保连接可靠。
TCP与UDP的对比
| 特性 | TCP | UDP |
|---|---|---|
| 连接类型 | 面向连接(需三次握手) | 无连接(直接发送) |
| 可靠性 | 可靠(保证交付、有序、无重复) | 不可靠(尽力而为,不保证交付) |
| 传输单位 | 字节流(无消息边界) | 数据报(保留消息边界) |
| 流量/拥塞控制 | 有(滑动窗口、拥塞控制算法) | 无(需应用层实现) |
| 首部开销 | 较大(20字节固定首部,可扩展) | 较小(8字节固定首部) |
| 延迟 | 较高(连接建立/维护开销) | 低(无连接开销) |
| 典型应用 | HTTP、FTP、邮件、远程桌面 | 直播、游戏、DNS、SNMP |
传输层与应用层的交互
-
端口号的作用:传输层通过端口号将数据分发给对应的应用程序,例如:
- 浏览器访问网页时,客户端随机选择一个动态端口(如50001),服务器通过80(HTTP)或443(HTTPS)端口响应。
- DNS客户端通过UDP 53端口发送查询请求,服务器通过UDP 53端口返回结果。
传输层的发展与扩展
- QUIC协议(Quick UDP Internet Connections)
- 基于UDP的新型传输层协议,由Google开发,旨在替代TCP。
- 特点:低延迟(减少握手次数)、多路复用、加密传输(内置TLS)、连接迁移(切换网络时保持连接)。
- 应用:HTTP/3协议基于QUIC,已被主流浏览器支持。
- SCTP协议(Stream Control Transmission Protocol)
- 面向连接的可靠传输协议,支持多流(Multi-Stream)和多宿主(Multi-Homing)。
- 应用:实时通信(如VoIP)、电信网络中的信令传输。
3.2 多路复用与多路分解
基本概念与核心作用
多路复用(Multiplexing)和多路分解(Demultiplexing)是计算机网络中实现资源共享与精准分发的关键机制,主要解决以下问题:
- 多路复用:在发送端将多个应用进程的数据合并到一条传输通道(如一条物理链路或一个传输层连接)中传输,提高资源利用率。
- 多路分解:在接收端将混合的数据按规则分离,准确交付给对应的应用进程。
核心作用: 在传输层(TCP/IP模型)中,这两个机制是实现“端到端通信”的基础,依赖**端口号(Port)**完成进程级的标识与分发。
- 在传输层(如TCP/UDP)中,通过端口号(Port Number)实现应用进程的标识与区分;
- 在网络层、数据链路层等更低层中,通过类似机制实现不同协议或设备的数据复用与分解。
多路复用(传输层发送端)
原理:
- 同一主机上的多个应用进程(如浏览器、邮件客户端、即时通信工具)可同时通过同一个传输层协议(TCP或UDP)发送数据。
- 传输层将各进程的数据封装成独立的报文段(Segment/UDP数据报),并在报头中添加源端口号(标识发送进程)和目标端口号(标识接收进程)。
- 所有报文段通过网络层的同一IP地址发送到网络中,共享底层网络资源(如带宽)。
示例:
- 客户端同时用浏览器(进程A,端口50001)访问网页(服务器80端口)和用QQ(进程B,端口50002)聊天:
- 进程A的数据 → 封装为TCP报文段,源端口50001,目标端口80;
- 进程B的数据 → 封装为UDP数据报,源端口50002,目标端口QQ服务器端口(如8000);
- 两者通过同一IP地址发送,共享网络层的IP协议。
多路分解(传输层接收端)
原理:
主机收到IP数据报:每个数据报有源IP地址,目的IP地址,每个数据报搬运一个数据段,每个数据段有源和目的端口号 。
主机用IP地址和端口号指明数据段属于哪个合适的套接字。
- TCP的多路复用/分解:
- 每个TCP套接字由四元组唯一标识:(源IP地址,源端口号,目标IP地址,目标端口号)。
- 例:同一服务器可通过不同目标端口号同时处理多个客户端的HTTP请求(如客户端A连接80端口,客户端B连接80端口,但源IP和源端口不同)。
- UDP的多路复用/分解:
- UDP 套接字由两个因素指定:(目的IP地址, 目的端口号),当主机收到UDP数据段:检查数据段中的目的端口号,用端口号指示UDP数据段属于哪个套接字。具有不同的源IP地址且/或源端口号,但具有相同的目的IP地址和目的端口号的IP数据报,指向同样的套接字
与其他层的多路复用/分解对比
| 层次 | 复用/分解对象 | 标识机制 | 典型场景 |
|---|---|---|---|
| 传输层 | 应用进程的数据 | 端口号(Port) | 浏览器与邮件客户端共享网络连接 |
| 网络层 | 不同协议的数据包 | 协议号(Protocol Number,如IP报头) | IP网络中同时传输TCP、UDP、ICMP数据 |
| 数据链路层 | 不同网络层协议的数据帧 | 类型字段(Type Field,如Ethernet) | 以太网中同时传输IP、ARP、RARP数据帧 |
| 物理层 | 不同信号或信道 | 频率、时间片、编码等 | 频分复用(FDM)、时分复用(TDM) |
常见问题与解决方案
- 端口冲突: 同一主机上的两个应用进程不能同时绑定同一个端口号。
- 解决方案:
- 服务器端:使用知名端口(需权限)或注册端口(避免冲突);
- 客户端:动态分配端口(操作系统自动管理,确保唯一性)。
- 解决方案:
- NAT(网络地址转换)中的端口复用:
- 家庭路由器通过NAT将多个设备的私有IP转换为同一公网IP时,通过端口号区分不同设备的连接(即NAPT,网络地址端口转换)。 例如:设备A(私有IP 192.168.1.2,端口50001)和设备B(192.168.1.3,端口50001)访问同一服务器时,路由器通过公网IP+不同端口号(如12345和12346)区分流量。
3.3 无连接传输:UDP
用户数据报协议(UDP,User Datagram Protocol)
特点:无连接、不可靠传输、基于数据报。UDP 只在 IP 的数据报服务之上增加了端口的功能和差错检测的功能。
应用场景:对实时性要求高、允许少量丢包的场景,如音视频直播(RTMP/RTSP)、视频会议(WebRTC)、在线游戏(FPS/MMO)、DNS查询、SNMP(网络管理)等。
核心机制:
- 无连接:发送数据前无需建立连接,直接封装数据报发送,延迟低。
- 不可靠传输:不保证数据到达、不保证顺序、不处理重复包,仅提供“尽力而为”的交付。
- 基于数据报:保留应用层的消息边界,发送方的每个UDP数据报对应接收方的一个消息。
•UDP 是面向报文的。发送方 UDP 对应用程序交下来的报文,在添加首部后就向下交付 IP 层。UDP 对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。
•应用层交给 UDP 多长的报文,UDP 就照样发送,即一次发送一个报文。
•接收方 UDP 对 IP 层交上来的 UDP 用户数据报,在去除首部后就原封不动地交付上层的应用进程,一次交付一个完整的报文。
•应用程序必须选择合适大小的报文。
UDP首部
UDP首部有8个字节,由4个字段构成,每个字段都是两个字节:
1.源端口: 源端口号,需要对方回信时选用,不需要时全部置0.
2.目的端口:目的端口号,在终点交付报文的时候需要用到。
3.长度:UDP的数据报的长度(包括首部和数据)其最小值为8(只有首部)
4.校验和:检测UDP数据报在传输中是否有错,有错则丢弃。
UPD检验:在计算检验和时,临时把“伪首部”和 UDP 用户数据报连接在一起。伪首部仅仅是为了计算检验和。
3.4 可靠数据传输原理
rdt协议
rdt(Reliable Data Transfer,可靠数据传输)协议是计算机网络中用于实现可靠数据传输的一系列理论模型和协议框架,其核心目标是在不可靠的底层网络上为上层提供可靠的数据传输服务。
- rdt1.0:适用于完美可靠信道,无 bit 错误和分组丢失。发送方将数据封装后发送到下层信道,接收方从下层信道接收数据并提取交付,采用分离的有限状态机(FSM)。
- rdt2.0:针对信道可能出现的 bit 错误,增加了校验和用于差错检测,接收方通过确认(ACKs)和否认(NAKs)反馈分组接收情况,发送方根据反馈重发分组。
- rdt2.1:解决 rdt2.0 中 ACK/NAK 混淆问题,发送方给分组加序号(0 和 1),接收方检查重复分组。发送方需检查 ACK/NAK 是否混淆,状态加倍;接收方要检查重复分组,且不知上一个 ACK/NAK 是否被正确接收。
- rdt2.2:与 rdt2.1 功能相同,但只用 ACKs。接收方在 ACK 中明确被确认报文序号,发送方收到重复 ACK 按 NAK 处理,即重发当前报文。
- rdt3.0:考虑下层信道报文丢失问题,发送方等待 “合理的” 确认时间,超时重发。接收方指定确认报文序号,需倒计时定时器,利用序号处理重复问题。如在 1 Gbps 链路、15 ms 端到端传输延迟、8000bit 报文的情况下,网络利用率较低,为 0.00027 。
流水线技术
1. 核心定义 允许发送方在未收到前一个报文确认(ACK)时,连续发送多个报文,形成“流水线”式传输,显著提升信道利用率。
2. 技术背景与优势
-
对比停止等待协议:发送方每发一个报文必须等待ACK,信道空闲时间长(如卫星通信中往返延迟达数百毫秒)。
流水线技术:将等待时间用于发送新数据。
发送方允许发送多个未确认报文,提高利用率。有 Go - Back - N 和选择性重传两种形式。Go - Back - N 发送方用 k 位序号,有发送窗口,接收方为正确接收的最高序号分组发 ACK,丢弃失序分组;选择性重传接收方分别确认收到的分组,缓冲失序报文,发送方只重发未确认分组。
滑动窗口协议
滑动窗口协议是流水线技术的基础实现。流水线技术允许发送方在未收到确认时连续发送多个分组(即“流水线”),而滑动窗口协议通过窗口大小限制流水线的长度,避免无节制发送导致的问题。
- 核心思想:
发送方和接收方各自维护一个“窗口”,用于标识允许发送或接收的数据范围。窗口大小表示在无需等待确认的情况下,可发送或接收的最大数据量,以此控制数据传输速率,避免网络拥塞或接收方缓冲区溢出。 - 主要功能:
- 流量控制:根据接收方处理能力动态调整发送速率,防止数据“淹没”接收方。
- 可靠传输:通过序号、确认机制和重传策略,确保数据无丢失、无重复、按序到达。
1. 发送方窗口
- 结构:窗口内包含三类数据分组(以序号从小到大排列):
- 已发送并确认:已收到ACK,可从窗口移除。
- 已发送未确认:等待接收方确认,若超时未确认则重传。
- 未发送但允许发送:窗口内未发送的分组,可直接发送。
- 滑动机制:当收到接收方对窗口内最小序号分组的确认时,窗口整体向前滑动,允许发送新的分组。
2. 接收方窗口
- 结构:窗口内标识允许接收的分组序号范围,仅接收序号在窗口内的分组,其他分组(如重复或失序)会被丢弃或缓存(取决于协议类型)。
- 滑动机制:当接收方成功接收窗口内最小序号的分组后,窗口向前滑动,通知发送方新的可发送范围(通常通过ACK报文携带窗口大小信息)。
Go-Back-N
发送方维护发送窗口,接收方仅确认最高序号正确分组,失序分组直接丢弃。
工作流程示例
- 发送方发送分组1-5,窗口覆盖1-5。
- 分组3在传输中丢失,接收方收到1、2、4、5后,仅对2发ACK(期望接收3)。
- 发送方收到ACK 2,但未收到ACK 3,超时后重传3~5。
选择性重传
接收方单独确认每个正确分组,缓存失序分组,发送方仅重传未确认分组。
核心优化
- 接收方改进:
- 对每个正确分组单独发ACK(如ACK 3、ACK 5),并缓存失序分组(如收到5后,若4未到则缓存5)。
- 当连续收到失序分组时,不立即丢弃,等待缺失分组补全后按序交付。
- 发送方改进:
- 仅重传未收到ACK的分组(而非全部后续分组),需维护“已发送未确认”分组的状态表。
工作流程示例
- 发送方发送分组1-5,窗口覆盖1-5。
- 分组3丢失,接收方收到1、2、4、5,分别发ACK 1、ACK 2、ACK 4、ACK 5,并缓存4、5。
- 发送方收到ACK 1、2、4、5,仅重传未确认的3。
- 接收方收到3后,将3与缓存的4、5按序交付。
3.5 面向连接传输:TCP
传输控制协议,可靠按序递交(TCP,Transmission Control Protocol)
特点:面向连接、可靠传输、基于字节流。不提供延迟保证和带宽保证。
报文段结构
TCP 序号和确认
序号:数据段中第一个字节在数据流中的位置编号。确认:期望从另外一边收到的下一个字节的序号。
问: 接收方如何处理失序的数据段 答: TCP规范没有明确规定, 由编程人员处理。
可靠数据传输机制
TCP 发送方通过 “序号 + 确认 + 滑动窗口 + 重传机制” 实现可靠传输
TCP发送方(简化):实现了 TCP 协议的滑动窗口机制核心逻辑,维护了两个关键变量:
NextSeqNum:指向下一个待发送段的序列号
SendBase:指向最早未被确认段的序列号(发送窗口的左边界)
NextSeqNum = InitialSeqNum # 初始化下一个要发送的序列号,用于标识新生成的TCP段
SendBase = InitialSeqNum # 初始化发送窗口的基序号,即最早未被确认的段的序列号
loop (forever) { # 主循环,持续监听事件
switch(event) # 根据不同事件类型执行相应操作
event: data received from application above # 上层应用有数据需要发送
create TCP segment with sequence number NextSeqNum # 创建TCP段,使用NextSeqNum作为序列号
if (timer currently not running) # 如果当前没有运行的定时器
start timer # 启动定时器,用于超时重传机制
pass segment to IP # 将TCP段传递给IP层进行网络传输
NextSeqNum = NextSeqNum + length(data) # 更新NextSeqNum,增加刚刚发送的数据长度
event: timer timeout # 定时器超时事件(说明可能有段丢失)
retransmit not-yet-acknowledged segment with smallest sequence number # 重传序列号最小的未确认段(即SendBase对应的段)
start timer # 重启定时器,继续等待确认
event: ACK received, with ACK field value of y # 收到ACK确认,确认号为y
if (y > SendBase) { # 如果确认号大于当前发送窗口基序号(说明有新的段被确认)
SendBase = y # 更新发送窗口基序号到y,滑动窗口
if (there are currently not-yet-acknowledged segments) # 如果仍有未确认的段
start timer # 重启定时器,等待剩余段的确认
}
} /* end of loop forever */
TCP发送方核心事件机制
1. 从应用程序接收数据
-
序号分配逻辑:
- 生成TCP报文段时,序号字段赋值为该报文段首个数据字节在整个字节流中的位置(如初始序号ISN=1000,数据长度100字节,则序号为1000,下一段为1100)。
- 示例:若字节流为
ABCDEFG(7字节),第一个报文段含ABC(3字节),则序号为0(假设ISN=0),下一段序号为3。
-
定时器启动条件:
- 若当前没有运行的定时器(即最早未确认的报文段未被计时),则启动定时器,计时对象为最早未确认的报文段(SendBase对应的段)。
-
超时间隔(TimeOutInterval)设置:
-
基于往返时间(RTT) 动态调整: 初始值通常设为默认值(如1秒),后续根据实际测量的RTT样本计算平滑往返时间(SRTT) 和偏差(RTT Deviation),公式如下:
SRTT = α × SRTT + (1-α) × RTT样本 (α通常为0.8~0.9) TimeOutInterval = SRTT + 4 × RTT Deviation
-
2. 超时事件处理
- 重传策略: 重传导致超时的报文段(即序号=SendBase的段,最早未被确认的段)。
- 示例:发送窗口为[1000, 2000],SendBase=1000,若1000号段超时,重传该段,而非窗口内所有段。
- 定时器管理: 重传后重启定时器,且超时间隔可能按指数退避策略增加(如超时一次后TimeOutInterval翻倍),避免网络拥塞时频繁重传。
3. 收到确认(ACK)事件处理
- 确认号(ACK Number)的作用: ACK号表示接收方期望接收的下一个字节序号,隐含前序字节已正确接收(如ACK=1000表示0~999字节已确认)。
- 窗口滑动逻辑:
- 若ACK号 > SendBase(即确认落在发送窗口内):
- 更新SendBase为ACK号,滑动发送窗口(如原SendBase=1000,ACK=1500,则窗口左边界右移至1500)。
- 若仍有未确认的报文段(SendBase < NextSeqNum),则重启定时器,继续计时新的最早未确认段。
- 若ACK号 > SendBase(即确认落在发送窗口内):
- 累积确认特性: TCP支持累积确认,即ACK=Y表示Y之前的所有字节均已确认(如发送1000、1500、2000号段,若1500丢失,接收方收到2000后仍发ACK=1000,直到1500被重传并确认)。
快速重传机制(Fast Retransmit)
1. 核心原理:通过重复ACK检测丢包,提前重传而非等待超时
- 重复ACK的产生场景:
- 当报文段n丢失时,后续报文段n+1、n+2等到达接收方后,接收方因发现序号不连续,会持续发送对n-1号段的ACK(即重复ACK)。
- 示例:发送段1、2、3,段2丢失,接收方收到1后发ACK=2,收到3时发现失序,再次发ACK=2(重复ACK),收到4时仍发ACK=2,形成多次重复ACK。
- 触发条件:发送方收到3个重复ACK(即同一ACK号连续出现3次),判定对应报文段丢失。
2. 快速重传流程
- 检测丢包:收到3个重复ACK(如ACK=1000出现3次),确认1000号段丢失。
- 立即重传:无需等待定时器超时,直接重传丢失的1000号段。
- 重启定时器:重传后启动定时器,计时新的最早未确认段。
- 优化措施:重传时可能调整拥塞窗口(cwnd)(如TCP Reno算法中,快速重传后执行“拥塞避免”策略)。
3. 快速重传 vs 超时重传
| 维度 | 快速重传 | 超时重传 |
|---|---|---|
| 触发条件 | 3个重复ACK | 定时器超时 |
| 延迟性 | 提前重传,减少平均延迟(约1~2RTT) | 需等待超时(可能数十秒) |
| 网络影响 | 更高效,避免超时重传的带宽浪费 | 超时后可能伴随指数退避,影响效率 |
| 适用场景 | 高带宽网络中快速恢复丢包 | 作为快速重传失败后的兜底机制 |
发送方关键变量与窗口模型
-
发送方三大核心变量:
- SendBase:发送窗口左边界,最早未确认的字节序号。
- NextSeqNum:下一个待发送的字节序号(发送窗口右边界)。
- CongestionWindow(cwnd):拥塞窗口大小,用于限制 “发送方在未收到确认前可发送的数据量”(与滑动窗口共同决定实际发送窗口,取其中最小值)。
-
发送窗口动态变化示例:
初始:SendBase=1000,NextSeqNum=1500(窗口大小500) 发送段1000~1499,收到ACK=1200 → SendBase=1200,窗口滑动至[1200, 1700] 若此时收到3个重复ACK=1200 → 快速重传1200号段,SendBase保持1200,直到收到正确ACK
| 接收方的事件 | TCP 接收方行为 |
|---|---|
| 期望序号的报文段按序到达. 所有在期望序号以前的报文段都被确认 | 延迟ACK. 等到 500ms看是否有下一个报文段,如果没有,发送ACK |
| 期望序号的报文段按序到达另一个按序报文段等待发送ACK | 立即发送单个累积ACK, 确认两个有序的报文段 |
| 收到一个失序的报文段,高于期望的序号,检测到缝隙 | 立即发送重复 ACK, 指出期望的序号 |
| 到达的报文段部分地或者完全地填充接收数据间隔 | 立即发送 ACK, 证实缝隙低端的报文段已经收到 |
流量控制
流量控制使用接收窗口:接收缓冲区的剩余空间,接收方在报文段中宣告接收窗口的剩余空间,发送方限制没有确认的数据不超过接收窗口。
连接管理
建立连接,三次握手
TCP在交换数据报文段之前在发送方和接收方之间建立连接:初始化TCP 变量(序号,缓冲区流控信息)
Step 1: 客户发送TCP SYN报文段到服务器,指定初始的序号,没有数据
Step 2: 服务器接收SYN, 回复 SYN/ACK 报文段,服务器分配缓冲区,指定服务器的初始序号
Step 3: 客户接收 SYN/ACK, 回复 ACK 报文段, 可能包含数据
关闭连接,四次挥手
**客户关闭套接字:**clientSocket.close
Step 1: 客户发送 TCP FIN 控制报文段到服务器
Step 2: 服务器接收 FIN, 回复 ACK,进入半关闭连接状态;
Step 3: 服务器发送FIN到客户,客户接收 FIN,回复 ACK,进入 “time wait”状态等待结束时释放连接资源
Step 4: 服务器接收 ACK,连接关闭。
TCP释放连接时为什么time_wait状态必须等待2MSL时间
TCP 协议的操作可以使用一个具有 11 种状态的有限状态机来表示
3.6 拥塞控制原理
拥塞是指源主机发送过多的数据导致网络来不及处理,表现:丢失分组 (路由器的缓冲区溢出),长延迟 (在路由器的缓冲区排队)
拥塞的原因与代价
(一)场景1:两个发送者、两个接收者、一个无限缓冲区路由器、不执行重发、链路带宽为C
- 假设每个主机最大可达吞吐量为C/2,总的吞吐量为C。 结果:当吞吐量达到C/2时,拥塞时延变得无限大。
无限缓冲区不能解决拥塞问题,仅能避免丢包,但无法控制时延。
吞吐量与时延的矛盾:当网络负载接近链路带宽时,时延会指数级增长。(排队论中的 M/M/1 队列模型 )
(二)场景2:一个有限缓冲区路由器、发送方重发丢失的报文
- 情况分析
- 总是重发:会增加额外的工作量。
- 仅当数据丢失时重发:相对合理,但仍有重发开销。
- 超时而没有丢失的报文重发:会导致同样的吞吐量需要比完美情况更大的带宽。
- 代价
- 无效工作量:重发本质是 “补传” 丢包,但丢包已消耗一次传输资源,重发相当于重复劳动。
- 带宽浪费:冗余分组占用链路带宽,例如原本 100KB 数据因重发变成 150KB,链路效率降低 33%。
(三)场景3:四个发送方、多跳路径、超时/重发
- 代价:当分组丢失后,任何上游路由器的发送能力都浪费了。
拥塞控制
(一)端到端拥塞控制
- 特点:没有从网络中得到明确的反馈,而是从端系统观察到的丢失和延迟推断出拥塞。
- 应用:TCP采用的方法。
(二)网络辅助的拥塞控制
- 特点:路由器给端系统提供反馈。
- 反馈方式 单bit指示拥塞:如SNA、DECnet、TCP/IP ECN、ATM等。指明发送者应该发送的速率。
(三)ABR(可用比特率)选学
- 性质:属于“弹性服务”。
- 工作原理
- 如果发送方通道“低载”,发送方应该利用有效带宽。
- 如果发送方通道拥塞,发送方应该调节到保证速率。
(四)ATM ABR拥塞控制(情况分析)选学
- RM(资源管理)信元
- 发送方式:由发送方发送,点缀在数据信元中。
- 信元中的bit设置:由交换机设置,其中NI bit表示速率不要增加(轻度拥塞),CI bit为拥塞指示。
- 接收方处理:不改变RM信元的bit,将其返回给发送者。
- ER(明确速率)域
- 作用:RM信元的两个字节的ER域,拥塞的交换机可能降低信元中的ER值,发送方的发送速率因此调整到通道支持的最低速率。
- EFCI位
- 设置:数据信元中的EFCI位在拥塞的交换机中设置为1。
- 影响:如果数据信元有EFCI且比RM先到,发送方会设置CI比特于返回的RM信元中。
3.7 TCP拥塞控制
TCP拥塞控制概述
(一)核心机制
- 端到端控制:不依赖网络层反馈,通过**发送方动态调整拥塞窗口(CongWin)**实现。
- 发送速率限制:发送窗口大小 = min(CongWin, RcvWindow),其中RcvWindow由接收方通告,CongWin由网络拥塞状态决定。
- 拥塞感知:通过丢包事件(超时或3个重复ACK)判断拥塞。
(二)关键公式 发送速率 = CongWin RTT ( Bytes/sec ) \text{发送速率} = \frac{\text{CongWin}}{\text{RTT}} \quad (\text{Bytes/sec}) 发送速率=RTTCongWin(Bytes/sec)
TCP经典拥塞控制
(一)慢启动(Slow Start)
当连接开始的时候以指数方式增加速率,初始速率慢但是呈指数快速增长,直到某个阈值或丢失。
- 初始状态:连接建立时,CongWin = 1 MSS(最大段大小)。
- 增长策略:每收到一个ACK,CongWin加1;每经过一个RTT,CongWin翻倍(指数增长)。
- 终止条件:达到**ssthresh(慢启动阈值)**或发生丢包事件。
(二)AIMD(加性增乘性减)
发送方增加传输速率(窗口大小),探测可用带宽,直到发生丢包事件
- 加性递增(Additive Increase):每个RTT内如果没有丢失事件发生,拥塞窗口增加一个MSS。
- 乘性递减(Multiplicative Decrease):发生丢包事件后将拥塞窗口减半。
- 效果:形成锯齿状窗口变化,在探测带宽和避免拥塞间平衡。
(三)对拥塞事件的反应
- 超时(Timeout)
- 处理方式:CongWin 立即设置为 1个 MSS; 窗口开始指数增长(进入慢启动);到达一个阈值后再线性增长
- 意义:超时被视为严重拥塞,强制降低发送速率。
- 收到三个重复ACK
- 处理方式(TCP Reno):CongWin 减半+3 (Reno版);然后,窗口线性增长,直接进入拥塞避免阶段
- 逻辑:3个重复ACK表明部分分组已到达,网络仍有传输能力,无需完全重置窗口。
- TCP Tahoe与Reno对比。Tahoe是比Reno更新的版本
| 版本 | 超时处理 | 3重复ACK处理 |
|---|---|---|
| Tahoe | CongWin置为1 MSS | 同超时处理 |
| Reno | 同Tahoe | 快速恢复(不重置窗口) |
TCP拥塞控制FSM图
(一)状态机核心逻辑
- 慢启动阶段:CongWin < ssthresh时,指数增长。
- 拥塞避免阶段:CongWin ≥ ssthresh时,线性增长(每RTT加1 MSS)。
- 快速恢复阶段(Reno):收到3重复ACK后,先调整窗口再线性增长。
(二)阈值动态调整
- 每次丢包后,ssthresh设为丢包前CongWin的一半,最小值为2 MSS。
TCP拥塞控制优化版本
(一)TCP CUBIC
-
核心思想:用立方(cube)函数调整窗口,在丢包后更快逼近最优带宽。
-
数学模型:
-
窗口增长公式:$ W(t) = W_{\text{max}} + C(t-K)^3 $
$ K :到达 :到达 :到达 W_{\text{max}} 的时间点, 的时间点, 的时间点, C $为常数。
-
-
优势:离$ W_{\text{max}} $越远增长越快,越近越慢,适合长肥管道网络。
-
应用:Linux默认拥塞控制算法,广泛用于Web服务器。
(二)明确拥塞通告(ECN)
-
网络辅助机制:路由器通过IP报头ToS字段标记拥塞(ECN=10或11)。
接收方在ACK中设置ECE位通知发送方,包括IP(IP头ECN位标记)和TCP(TCP头C、E位标记)。
-
优势:在丢包前预警,减少重发开销。
(三)基于时延的拥塞控制
TCP(传统的Tahoe/Reno, CUBIC)提高TCP的发送速率,直到某些路由器的输出出现数据包丢失——此路由器即为瓶颈链路
- TCP Vegas:目标:维持端到端管道“刚好填满”,避免队列积压。机制:通过监测RTT变化调整速率,而非依赖丢包。
- BBR:开发者:Google,部署于骨干网络。核心:同时测量瓶颈带宽和最小RTT,动态调整发送速率。
- 其他算法:TIMELY、复合TCP(CTCP)、FAST等。
TCP公平性与挑战 (选学)
(一)公平性原理
- 理想情况:K个TCP连接共享带宽R时,每个连接获得R/K的平均速率。
- 实现机制:AIMD的对称调整,确保各连接按比例分配带宽。
(二)公平性挑战
- UDP竞争:UDP不执行拥塞控制,可能抢占TCP带宽。应用场景:多媒体传输(容忍丢包,需固定速率)。
- 并行TCP连接:Web浏览器打开多个连接,可能获取超过公平份额的带宽。示例:11个并行连接可抢占超过50%的链路带宽。
(三)特殊网络场景挑战
针对各种特定场景开发了具有不同特性的TCP版本
| 场景 | 挑战 |
|---|---|
| 长肥管道 | 大量数据传输,丢包导致效率骤降 |
| 无线网络 | 链路噪声导致误判拥塞 |
| 高延迟链路 | RTT过长影响窗口调整效率 |
| 数据中心网络 | 对延迟敏感,需低抖动控制 |
第四章 网络层
4.1 概述
网络层功能
-
功能:从发送方主机传输报文段到接收方主机,发送方主机封装报文段(segments)为数据报(datagrams)。接收方主机递交报文段给传输层在每个主机、路由器上都需要运行网络层协议。路由器会检查通过它的所有IP数据报的头部字段,然后根据目的IP地址对数据报进行转发。
-
如今的因特网网络层不执行连接建立
-
两个主要功能:路由与转发
路由是确定分组从发送方到接收方所经路径的过程;转发是将分组从路由器的输入端口转移到正确输出端口的操作。
路由算法确定端到端路径,转发表确定本地转发。
网络层组成
- 数据平面:本地的,每个路由器自身的功能决定抵达路由器输入端口的数据包如何转发到输出端口。两种数据平面的实现方式:
1.传统的路由算法: 在路由器内实现;2.软件定义网络(software-defined networking, SDN): 在远程服务器上实现 - 控制平面:整个网络范围,决定数据报在端到端路径上的路由器之间如何路由。传统方式下每个路由器有单独路由算法组件,通过交互实现控制;SDN方法中,由分离的远程控制器和路由器本地控制代理交互实现控制。
网络层服务模型
- 因特网服务:提供尽力而为服务,分组定时、接收顺序和交付都无法保证。
- 可能服务:包括确保交付、具有时延上界的确保交付、有序分组交付、确保最小带宽和确保最大时延抖动等。
4.2 虚电路和数据报网络
连接服务对比:数据报网络提供无连接服务,类似UDP; 虚电路网络提供连接服务,类似TCP,网络层的面向连接服务在端系统及网络核心的路由器中实现,传输层则在网络边缘的端系统中实现。 任何网络中的网络层只提供两种服务之一,不会同时提供。
虚电路网络
源于电话网络,网络功能复杂,端系统设备简单。
- 虚电路网络特点:数据传输前需建立连接,分组携带VC标识符,路由器维护连接状态,可分配资源。
数据报网络
数据报网络源于互连计算机网络,网络层服务模型简单,端系统功能复杂。高层实现许多功能。
- 数据报网络特点:无呼叫过程,路由器不维护连接状态,使用目的主机地址转发分组,转发表采用地址范围建立表项,通过最长前缀匹配查找输出端口。
路由器查表转发
路由器转发表只维持转发状态信息;转发表由选路算法修改(1~5分钟更新);虚电路网络转发表随虚电路的建立和拆除更新。一个端系统发送给另一个端系统的一批分组可能在网络中选择不同的路径,到达的顺序可能不一致。
4.3 路由器的工作原理
路由器结构
很重要的图!!
核心功能是运行路由算法和转发分组,由交换结构、输入端口、输出端口和选路处理器组成。
输入端口功能
包含线路端接、数据链路处理和查找转发模块,实现分组接收、链路层功能和查找转发,可能出现排队和线头阻塞。 
查找与转发
定义:确定到达分组通过交换结构转发至哪个输出端口,通过输入端口内存中的转发表实现。
分布式交换机制
选路处理器计算转发表,给每个输入端口存放一份转发表拷贝。在每个输入端口本地做出交换决策,无须激活中央选路处理器。避免在路由器中某个单点产生转发处理瓶颈。目的:以线速完成输入端口的处理
排队
交换结构
经内存交换受总线带宽限制;经总线交换每次仅一个分组传输,受总线速率限制;经交换矩阵交换可同时传输多个分组,速率较高。
内存交换
输入端口与输出端口之间的交换由CPU(选路处理器)控制完成;
当分组到达输入端口时,通过中断向选路处理器发出信号,将分组拷贝到处理器内存中;
选路处理器根据分组中的目的地址查表找出适当的输出端口,将该分组拷贝到输出端口的缓存中。
交换速度受总线带宽的速度限制 (每个分组穿过两次总线)
若总线带宽为每秒写入或读出B个分组,则总的转发吞吐量 (分组从输入端口被传送到输出端口的总速率)小于B/2。
总线交换
输入端口通过一条共享总线将分组直接传送到输出端口,不需要选路处理器的干预。
每次只能有一个分组通过总线传送。分组到达一个输入端口时,若总线正忙,会被暂时阻塞,在输入端口排队。
路由器交换带宽受总线速率限制。
交换矩阵交换
纵横式交换机:由2n 条总线组成,n 个输入端口与n 个输出端口连接。
到达输入端口的分组沿水平总线穿行,直至与所希望的输出端口的垂直总线交叉点:
若该条垂直总线空闲,则分组被传送到输出端口;否则,该到达的分组被阻塞,必须在输入端口排队
输出端口功能
取出存放在输出端口内存中的分组,并将其传输到输出链路上。
当交换结构将分组交付给输出端口的速率超过输出链路速率,就需要排队与缓存管理功能。当输出端口的缓冲区溢出时,就会出现延时和丢包。
如何管理缓存中的数据包?——包调度(packet scheduling)
FCFS(FIFO,先来先服务);基于优先级的调度;Round Robin(轮询);加权公平排队(Weighted Fair Queuing , WFQ)
4.4 网际协议(IP)☆
IP数据报格式与分片重组
- 数据报基本结构
- 固定首部:20字节,包含版本号(ver,4位,如IPv4为4)、首部长度(IHL,4位,以4字节为单位,最小5即20字节)、服务类型(TOS,8位)、总长度(16位,含首部和数据)、标识符(16位,分片标识)、标志(3位,DF禁止分片,MF后续分片)、段偏移(13位,分片在原数据报中的位置,单位8字节)、寿命(TTL,8位,最大跳数)、首部检查和(16位,仅校验首部)、源/目的IP地址(各32位)。
- 数据部分:可变长,通常承载TCP/UDP段,最大长度受MTU限制。MTU 指数据链路层允许传输的单个数据帧的最大字节数
- 分片与重组机制
- 原因:不同数据链路MTU不同(如以太网MTU为1500字节),大分组需分割。
- 分片标识:同一数据报分片共享相同标识符,通过段偏移(offset)和标志位(MF=1表示非最后分片,DF=1禁止分片)重组。
- 示例:4000字节数据报(MTU=1500字节)分为3片,首片数据1480字节(MTU-20字节首部),段偏移0,MF=1;末片数据1040字节,段偏移370(1480×2/8),MF=0。
IPv4地址体系与分类
IP 地址: 分配给主机或路由器接口的标识符,用于在网络中定位和区分设备。
接口: 主机/路由器与物理链路之间的边界。路由器有多个接口,主机可以有多个接口,每个接口有一个IP地址
IP地址有两种:IPV4和IPV6
IPV4:32个二进制位长(4字节),常用点分十进制表示;
IPV6:128个二进制位长(16字节)常用冒号分隔表示。
同一局域网上的主机或路由器的IP地址中的网络号必须相同。交换机互连的网络仍然是一个局域网,只能有一个网络号。
路由器总是具有两个或两个以上IP地址。两个路由器直接相连时,在连线两端的接口处,可以指明IP地址也可以不指明IP地址。
-
地址结构
- 32位二进制:点分十进制表示,如223.1.1.1=11011111.00000001.00000001.00000001。
- 两部分组成:网络号(标识主机所在网络)+主机号(标识网络内主机)。
-
传统五类地址
类别 前缀标识 网络号长度 主机号长度 地址范围 适用场景 A类 首位0 8位 24位 1.0.0.1-127.255.255.254 大型网络(如跨国企业) B类 前两位10 16位 16位 128.0.0.1-191.255.255.254 中型网络(如大学) C类 前三位110 24位 8位 192.0.0.1-223.255.255.254 小型网络(如企业部门) D类 前四位1110 - - 224.0.0.1-239.255.255.254 用于多播 E类 前五位11110 - - 240.0.0.1-255.255.255.254 为未来的需求保留的 -
特殊地址段
- 回环地址:127.0.0.1-127.255.255.254,用于本地环回测试,不对外通信。
- 私有地址:10.0.0.0-10.255.255.255(1个A类块)、172.16.0.0-172.31.255.255(16个B类块)、192.168.0.0-192.168.255.255(256个C类块),仅限局域网使用,公网不路由。
- 特殊用途:0.0.0.0(未指定网络)、255.255.255.255(本网段广播地址)。
子网划分与子网掩码
子网的定义:设备接口的IP地址具有同样的网络部分。没有路由器的介入,物理上能够相互到达
-
划分子网原理
- 借位规则:从主机号高位借用n位作为子网号,剩余m位为主机号,子网数= 2 n 2^n 2n,每个子网主机数= 2 m − 2 2^m - 2 2m−2(排除全0子网号和全1广播地址)。
- 示例:网段202.114.1.0/24(C类)划分为2个子网,借1位子网号,子网掩码255.255.255.128(前25位1),子网号为0和128。
-
子网掩码计算
子网掩码长为32位比特,其中的1对应于IP地址中的网络号和子网号,而子网掩码中的0对应于主机号。
- 作用:子网号字段长度是可变的,因此,为了确定子网地址,IP协议提供了子网掩码 。用于确定网络地址(网络号+子网号)和主机地址,通过IP地址与掩码按位与运算得到网络地址。 网络地址是 IP 地址的一部分,表示一个网络的 “标识符”,用于标识一个特定的网络。
- 示例:IP=187.163.22.11,掩码=255.255.255.128(二进制前25位1),网络地址=187.163.22.0。

-
路由表变化
- 未划分子网:路由表含“目的网络地址”(存储网络地址而不是IP从而减少存储量)和“下一跳”,如30.0.0.0→40.0.0.7。
- 划分子网后:增加“子网掩码”字段使得能够定位到子网,如128.30.33.0/255.255.255.128→接口0。

CIDR无分类域间路由
传统IP地址分类方式分配IP被CIDR技术取代。使用斜线记法,又称为CIDR记法来区分网络前缀和主机号,即在IP地址后面加上一个斜线“/”,斜线后面用一个数字指定网络前缀的长度。即CIDR地址格式=网络前缀+主机号。
- 传统分类:A类浪费(24位主机号)、C类不足(8位主机号),地址利用率低。
- CIDR:按需分配地址块,支持超网聚合,解决地址浪费与不足问题,成为现代互联网主流编址技术。
-
核心技术特点
- 无类别编址:摒弃A/B/C类,用“IP地址/网络前缀长度”表示(如206.0.68.0/22),前缀长度可变(1-32位)。
- 地址聚合:将连续网络前缀的地址块聚合成超网( 一个CIDR地址块可以表示分类IP的多个分类地址),减少路由表条目,提升路由效率。例如,4个C类地址(206.0.68.0-206.0.71.255)可聚合成206.0.68.0/22。
-
层次化地址分配
单位 地址块 二进制前缀 地址数 说明 ISP 206.0.64.0/18 11001110.00000000.01* 16384 顶级分配块 大型单位 206.0.68.0/22 11001110.00000000.010001* 1024 从ISP细分 中型单位 206.0.68.0/23 11001110.00000000.0100010* 512 进一步细分 小型单位 206.0.71.0/25 11001110.00000000.01000111.0* 128 最小分配单元
DHCP
问: 主机如何得到IP地址?
1.手工指定(保存在系统配置中):Windows: 控制面板->网络,UNIX/LINUX: 在/etc/rc.config中,可使用ipconfig命令配置。
2.自动从一个DHCP服务器得到IP地址,方便灵活
DHCP(Dynamic Host Configuration Protocol,动态主机配置协议) 是一种用于自动分配网络配置参数的网络协议,应用层协议,基于客户机 / 服务器模型。其核心功能是为局域网内的设备动态分配 IP 地址、子网掩码、客户的第一跳路由器的地址(网关)、DNS 服务器IP地址或域名等网络参数,避免手动配置的繁琐和地址冲突问题。
工作过程
1:DHCP 服务器被动打开 UDP 端口 67,等待客户端发来的报文。
2:DHCP 客户从 UDP 端口 68发送 DHCP 发现报文。
3:凡收到 DHCP 发现报文的 DHCP 服务器都发出 DHCP 提供报文,因此 DHCP 客户可能收到多个 DHCP 提供报文。
4:DHCP 客户从几个 DHCP 服务器中选择其中的一个,并向所选择的 DHCP 服务器发送 DHCP 请求报文。
5:被选择的 DHCP 服务器发送确认报文DHCPACK,客户进入已绑定状态,并可开始使用得到的临时 IP 地址了。
DHCP 客户现在要根据服务器提供的租用期 T 设置两个计时器 T1 和 T2,它们的超时时间分别是 0.5T 和 0.875T。当超时时间到就要请求更新租用期。
6:租用期过了一半(T1 时间到),DHCP 发送请求报文 DHCPREQUEST 要求更新租用期。
7: DHCP 服务器若不同意,则发回否认报文DHCPNACK。这时 DHCP 客户必须立即停止使用原来的 IP 地址,而必须重新申请 IP 地址(回到步骤2)
8: DHCP 服务器若同意,则发回确认报文DHCPACK。DHCP 客户得到了新的租用期,重新设置计时器。
若DHCP服务器不响应步骤6的请求报文DHCPREQUEST,则在租用期过了 87.5% 时,DHCP 客户必须重新发送请求报文 DHCPREQUEST(重复步骤6),然后又继续后面的步骤。
9:DHCP 客户可随时提前终止服务器所提供的租用期,这时只需向 DHCP 服务器发送释放报文 DHCPRELEASE 即可。
组织怎样获取IP地址中的网络号部分?从ISP的地址空间中划分一块给申请者
ISP获得地址块的方法——从ICANN获取
NAT网络地址转换
对外部网络来讲,本地网络只用一个IP地址,不需要从 ISP分配一系列地址,一个IP地址用于所有设备。
在本地网络,改变设备的IP地址不用通知外部世界,可以变更 ISP ,不用改变本地网络的设备的地址。
本地网络内部设备不能被外部世界明确寻址,或是不可见 (增加了安全性)。
争议:网络地址端口转换需修改 TCP/UDP 端口号(第四层字段),但路由器只应该处理到第三层,违反了端到端主张
执行NAT,路由器必须做到:
外出的分组: 替换每个外出的分组的 (源IP 地址, 端口号) 为 (NAT IP 地址, 新端口号)
远程客户/服务器用(NAT IP地址, 新端口号)作为目的地来响应。
(在NAT转换表中)记录每个(源IP 地址, 端口号)到 (NAT IP地址, 新端口号) 转换配对。
进来的分组: 对每个进来的分组,用保存在NAT表中的对应的(源IP 地址, 端口号) 替换分组中的目的域 (NAT IP 地址, 新端口号)。
ICMP
(Internet Control Message Protocol,因特网控制报文协议)
协议定位
- 用于主机、路由器之间交流网络层信息,核心功能包含:
- 差错报告:告知网络层错误(如不可达的主机、网络、端口、协议等)。
- 请求/应答:支撑网络诊断工具(如
ping基于 ICMP 请求/应答;traceroute依赖 ICMP 超时报文 + 端口不可达报文 )。
- 协议层级:位于 IP 之上 ,ICMP 消息封装在 IP 分组中传输(即 ICMP 报文是 IP 分组的载荷 )。
Traceroute:基于 ICMP 的路径追踪机制
traceroute 用于追踪数据包从源端到目的端的网络路径,并记录每一跳(路由器)的响应时间,其核心逻辑依托 TTL(生存时间) 和 ICMP 报文交互 实现:
- 源端发送 UDP 分组(利用 TTL 逐跳探测)
- 源端向目的端发送一系列 UDP 分组,特点是:
- 首组 TTL = 1,后续分组 TTL 逐次 + 1(如第二组 TTL = 2,第三组 TTL = 3 …… 以此类推 )。
- 使用高位未注册 UDP 端口(如 33434 及以上),目的端通常无对应服务监听。
- 路由器因 TTL 超时报文(ICMP Type 11)返回路径信息
- 当第 n个 UDP 分组(TTL = n)到达第
n跳路由器时:- 路由器检测到 TTL 减为 0(或经自身转发后 TTL 耗尽 ),会丢弃该 UDP 分组。
- 同时,路由器向源端返回 ICMP 超时报文(Type = 11,Code = 0 ),报文中包含自身的名称和 IP 地址。
- 源端接收 ICMP 报文,计算 RTT 并记录路径
- 源端收到路由器返回的 ICMP 超时报文后:
- 计算往返时间 RTT(从发送 UDP 分组到收到 ICMP 报文的时间差 )。
- 为保证结果可靠性,对每个 TTL 值会发送 3 次 UDP 分组,取 RTT 统计值(如平均值、最小值 )。
- 目的端返回 ICMP 端口不可达,结束追踪
- 当 UDP 分组最终到达目的端时:
- 因目的端无对应 UDP 端口的服务(高位未注册端口 ),会返回 ICMP 端口不可达报文(Type = 3,Code = 3 )。
- 源端收到该报文后,判定路径追踪结束,停止发送后续 UDP 分组。
IPv6
采用 128 位二进制数 表示。IPv6 数据报格式:固定长度的 40 字节首部,不允许分片
例如:104.220.136.100.255.255.255.255.0.0.18.128.140.10.255.255
用冒号十六进制表示为: 69DC:8864:FFFF:FFFF:0:1280:8C0A:FFFF
零压缩表示法:前导零压缩,连续零段压缩。
例如:FF0C:0:0:0:0:0:B1零压缩表示为:FF0C::B1
地址2001:0000:0000:0db8:0000:0000:7334可压缩为:2001::db8::7334
4.5 路由和选路☆
默认路由器:与主机直接相连的路由器,又叫第一跳路由器。每当主机发送一个分组时,都先传送给它的默认路由器。
从源主机到目的主机的选路归结为从源路由器到目的路由器的选路。
路由算法:是确定一个分组从源路由器到目的路由器所经路径的算法。
路由算法的关键:在给定的一组路由器以及连接路由器的链路中,找到一条从源路由器到目的路由器的“好”路径(开销最小,热土豆选路)。
路由算法分类:按信息获取方式分为全局路由算法(如链路状态路由算法LS)和分布式路由算法(如距离向量路由算法DV);按路径变化特性分为静态和动态路由算法。
链路状态路由算法(LS)
基于Dijkstra算法,所有节点知道网络拓扑和链路费用,通过链路状态广播实现,计算源节点到所有其他节点的最低费用路径,算法复杂度为 O ( n 2 ) O(n^2) O(n2) ,可能产生振荡。
c(x,y):表示从节点x到y的链路费用; = ∞ 如果不是直接邻居
D(v):表示从源节点到目的节点v的当前路径的费用;
p(v):表示从源节点到目的节点v的路径上的前驱节点(例如w是v的前驱节点);
N’:表示已经找到最低费用路径的节点集合。
例题
构建最低费用路径树
例题
距离向量路由算法(DV)
距离向量路由算法是一种迭代的、异步的和分布式的能自我终结算法。
分布式:每个节点都从其直接相连邻居接收信息,进行计算,再将计算结果分发给邻居。
对每个节点x(1)初始化;(2)更新自己的距离向量:每个节点不断向邻居发送其距离向量拷贝;当节点x收到一个邻居v的新距离向量,先保存,并用B-F公式更新自己的距离向量 ;(3)重复执行(2),直到没有更新的距离向量发出
4.6 层次选路
层次选路指将大型网络(如因特网)划分成多个自治管理的区域(自治系统 AS 为典型单位 ),不同层次 / 区域内运行适配的路由协议,实现 “域内高效转发 + 域间策略控制” 的分层路由机制
域内路由协议
域内路由协议,也被称作内部网关协议 (IGP)。 标准的域内路由协议:RIP: 路由信息协议;OSPF: 开放式最短路径优先;IGRP: 内部网关路由协议 (Cisco 所有)
RIP(路由信息协议)
1. 工作原理
- 算法基础:基于 距离向量算法(Bellman-Ford 算法),通过“跳数”衡量路由距离(最大跳数为 15,16 表示不可达)。
- 更新机制:路由器周期性(默认 30秒)向邻居节点广播自己的 路由表,内容包括目标网络、下一跳地址和跳数。
- 路由决策:选择跳数最少的路径,若跳数相同则任选其一(不支持负载均衡)。
2. 工作过程
- 初始化
路由器启动后,从直连网络获取路由信息(跳数为 0),并构建初始路由表。 - 周期性更新
每隔 30 秒,向所有 RIP 邻居(通过 UDP 520 端口)广播完整路由表。- 邻居收到更新后,计算到达各目标网络的新跳数(自身跳数 + 1),若新路径更优(跳数更小),则更新路由表。
- 若超过 180秒 未收到某条路由的更新,标记该路由为“不可达”(跳数设为 16);超过 240秒 仍未更新,则从路由表中删除。
- 水平分割与毒性逆转
- 水平分割:禁止从接收路由的接口再发回该路由,避免简单环路。
- 毒性逆转:当路由不可达时,主动向邻居发送“跳数 16”的更新,加速环路破除。
- 路由收敛
网络拓扑变化时(如链路故障),故障路由器先更新自身路由表,再通过周期性更新逐步扩散到全网,收敛速度较慢(可能产生临时环路)。
OSPF(开放最短路径优先协议)
1. 工作原理
- 算法基础:基于 链路状态算法(Dijkstra 算法),通过“代价”(Cost,与带宽成反比)衡量路由优劣。
- 分层结构:将网络划分为 区域(Area),包括一个 骨干区域(Area 0) 和多个非骨干区域,区域间通过骨干区域通信,减少路由计算复杂度。
- 安全机制:支持认证(明文、MD5、SHA 等),确保路由更新的合法性。
- 多路径支持:允许等价路由(相同 Cost)实现负载均衡。
2. 工作过程
- 邻居发现
通过组播(224.0.0.5)发送 Hello 报文,发现相邻路由器并建立 邻居关系(需满足区域、认证、网络类型等匹配条件)。 - 邻接关系建立
邻居间通过 数据库描述(DBD)报文 交换链路状态数据库(LSDB)摘要,并用 链路状态请求(LSR) 和 链路状态更新(LSU) 报文同步完整 LSDB。 最终形成 邻接关系(仅在 DR/BDR 与其他路由器间或点到点网络中建立)。 - 链路状态更新
当网络拓扑变化时(如链路故障、路由器加入/退出),触发 LSU 报文 向全网泛洪(Flooding)更新信息,确保所有路由器的 LSDB 一致。 泛洪过程通过 序列号 和 校验和 保证可靠性,避免重复或过时的更新。 - 路由计算
每个路由器基于本地 LSDB,使用 Dijkstra 算法 计算到达所有目标网络的最短路径树(SPF Tree),生成 路由表。 - 路由维护
- 定期(默认 30 分钟)发送 Hello 报文 维持邻居关系。
- 当 LSDB 发生变化时,重新计算路由;若无变化,则不主动更新(仅周期性确认数据库同步)。
域间路由协议(BGP)
BGP核心定位与功能
- 地位:AS间选路的事实标准协议,用于实现跨自治系统的路由信息交换。
- 三大核心任务:
- 子网可达性管理:从相邻AS获取子网可达信息(如“AS2可到达网络X”),并向全网通告自身子网存在(“I am here”)。
- 可达性信息传播:通过AS内路由协议(如OSPF)将域间路由同步到AS内所有路由器。
- 策略路由决策:基于AS策略和可达信息,选择到达目标子网的“好”路由(如优先选择客户网络路径)。
AS域间任务与选路逻辑
- 任务场景:当AS内路由器收到发往域外的分组时,需决策转发至哪个网关路由器。
- 选路协作:
- 域间协议:获取跨AS的子网可达路径(如AS1通过AS2和AS3均可达网络X)。
- 域内协议:计算AS内到各网关的最低开销路径(如Router 1d通过接口I到达网关1c的开销最小)。
- 热土豆选路(Hot Potato Routing):优先选择AS内到网关最小开销路径的网关,即使跨AS路径更长(如AS1选择更近的网关1c而非1b)。
BGP会话机制与信息传播
-
会话类型:
类型 作用 通信对象 TCP端口 TTL限制 eBGP 跨AS路由交换 不同AS路由器 179 默认1 iBGP AS内路由同步 同AS路由器 179 默认255 -
通告流程:
- eBGP会话:AS3通过路由器3a向AS1的1c通告前缀X可达。
- iBGP扩散:1c通过iBGP会话将前缀X同步到AS1内所有路由器(如1d、1b)。
- 跨AS再通告:1b通过eBGP会话向AS2的2a通告前缀X可达。
路径属性与路由构成
-
路由定义:前缀+路径属性=路由,属性用于描述路由特征和策略。
-
核心属性:
属性名称 作用 AS-PATH 记录路由经过的AS列表(如“AS3 AS1”),用于防环(拒绝包含自身AS的路由) NEXT-HOP 指示跨AS的下一跳路由器IP(如AS1到AS3的下一跳为1c) -
策略应用:网关路由器通过输入策略过滤路由(如AS1拒绝AS2的非客户路由)。
BGP选路规则与优先级
- 排除规则:按顺序筛选,直至仅剩一条路由。
- 核心优先级:
- 本地偏好值(Local Preference):AS内自定义优先级,值越高越优先(如优先选择本AS出口)。
- AS-PATH长度:路径越短越优先(如AS3→AS1优于AS3→AS2→AS1)。
- NEXT-HOP距离:AS内到网关的开销越小越优先(热土豆选路)。
BGP报文类型与功能
| 报文类型 | 功能描述 |
|---|---|
| OPEN | 建立TCP连接,协商版本、AS号,完成认证 |
| UPDATE | 通告新路由(携带前缀和属性)或撤销旧路由(携带不可达前缀列表) |
| KEEPALIVE | 周期性(默认30秒)维持会话连接,确认邻居存活 |
| NOTIFICATION | 报告协议错误(如格式错误、认证失败),终止会话 |
eBGP与iBGP会话的核心区别
eBGP:用于不同AS间的路由交换,默认TTL=1(限制跨AS跳数),需显式配置邻居关系,路由通告时携带完整AS-PATH。
iBGP:用于同一AS内的路由同步,TTL=255(允许跨多个路由器),无需物理直连,需遵守“iBGP水平分割”原则(不从接收接口转发iBGP路由,避免环路)。
4.7 软件定义网络SDN
- 概念与特点:软件定义网络是一种网络设计理念,具有控制平面和转发平面分离、开放性可编程的特点。SDN的核心思想是建立一个通用转发体系——每个交换设备包含一个流表(flow table)。 流表由一个逻辑上中心化的控制器(远程控制器)来计算和分发。
- 相关案例与优势:Google用SDN互联数据中心,提升带宽利用率,降低故障收敛时间。SDN具有统一管理、解决设备多样化等优势。
第五章 数据链路层
5.1 概述
链路层核心职责
-
将数据报从一个节点(主机或路由器)通过物理链路(有线或无线)传输到相邻节点。
-
处理对象:相邻节点间的单跳通信(区别于网络层的端到端通信)。
-
数据帧(Frame):链路层的协议数据单元,由数据报+帧头/帧尾封装而成,用于在链路上传输。在数据帧头部中,用MAC地址来标识源目的MAC地址。
链路层提供的服务和以太网能够提供的链路层服务是两个不同的概念。
第一个服务是:将数据报封装成数据帧,增加相应的头部和尾部信息,然后对于共享链路,能够接入链路
第二个服务是:在相邻节点之间可靠传输数据帧,当传输链路是比特错误率很低的链路时,例如光纤和双绞线,很少使用可靠数据传输机制;而在无线链路这样的高比特错误率链路时,通常会增加可靠数据传输机制。
思考一个问题:既然在传输层实现了端到端的可靠数据传输,为什么还需要在链路层提供可靠数据传输呢?
链路层负责相邻节点(主机 - 路由器、路由器 - 路由器等) 间的可靠传输,仅关注 “一段物理链路” 的数据转发。若链路层不保证可靠,即使传输层有端到端机制,局部链路的错误也会拖慢整体传输效率。
链路层六个主要服务
| 服务类型 | 功能描述 | 技术实现 |
|---|---|---|
| 封装成帧,链路接入 | 将网络层数据报封装为数据帧,添加帧头(源/目的MAC地址等)和帧尾(校验信息)。 | 帧头包含MAC地址(标识相邻节点),帧尾通常含CRC校验码。 |
| 可靠传输 | 确保数据帧在相邻节点间无差错、有序交付(非所有链路层必选,如以太网无此服务)。 | 差错检测:CRC校验。 重传机制:ARQ协议(停止等待、滑动窗口)。 序号与确认。 |
| 流量控制 | 限制发送方速率,避免接收方缓冲区溢出。 | 滑动窗口协议(如TCP链路层的流量控制)。 接收方反馈“窗口大小”通知发送方。 |
| 差错检测 | 检测传输中因噪声等导致的比特错误。 | CRC(循环冗余校验)、奇偶校验等算法,通过帧尾校验字段实现。 |
| 差错纠正 | 自动纠正检测到的比特错误(较少用,因重传更高效)。 | 海明码等前向纠错(FEC)技术,常见于无线链路(如802.11)。 |
| 双工模式 | 半双工:节点不能同时收发数据(如早期以太网)。 全双工:可同时收发(现代主流模式)。 | 取决于物理链路特性和设备支持(如双绞线支持全双工,同轴电缆仅半双工)。 |
链路层的实现位置
在主机和网络设备(路由器)上实现,是硬件,软件,固件的组合。在主机上,链路层的主体部分是在网络适配器上实现的(称为网卡)。
链路层控制器的许多功能是用硬件实现的。
在发送方,链路层控制器将数据报封装成数据帧,增加差错检测比特,可靠数据传输,流量控制等机制。
在接收方,链路层控制器接收数据帧,执行差错检测、可靠数据传输、流量控制等机制,最后从数据帧中抽取数据报,递交给上层。
链路层与MAC地址
-
MAC地址(物理地址)
- 定义:固化在网络适配器(网卡)中的48位标识符,全球唯一(由IEEE分配前24位厂商代码,后24位厂商自定义)。
- 作用:标识链路层通信的源/目的节点(区别于网络层的IP地址,IP地址标识端到端通信的逻辑主机)。
- 示例:
00:1A:2B:3C:4D:5E(十六进制表示)。
-
MAC地址与IP地址的区别
维度 MAC地址 IP地址 层次 链路层(硬件标识) 网络层(逻辑标识) 作用范围 相邻节点间的单跳通信 端到端的跨网络通信 动态性 固定(除非更换网卡) 动态分配(如DHCP)或静态 协议关联 用于以太网帧、802.11帧等 用于IP数据报
5.2 差错检查和纠错
概述
这里的差错检测和纠正技术主要针对的是比特错误。对一个节点发送到一个相邻节点的帧,检测是否出现比特差错,并纠正。
差错检测并非100%可靠,协议可能丢失一些错误,差错校验位越多,检测和纠正功能越好。
发送节点
接收节点
三种检测技术
奇偶校验
将要传信息D(d比特)划分为i行j 列(i 个组,每组j位);对每行和每列分别计算奇偶值;结果的i+j+1个奇偶比特构成了帧的差错检测比特。
二维奇偶校验
Internet校验和
**发送方:**将数据的每两个字节当作一个16位的整数,可分成若干整数;将所有16 位的整数求和;对得到的和逐位取反,作为检查和,放在报文段首部,一起发送。
接收方: 对接收到的信息 (包括检查和)按与发送方相同的方法求和。全“1”:收到的数据无差错;其中有“0”:收到的数据出现差错。
优缺点:分组开销小:检查和位数比较少;差错检测能力弱。适用于运输层(差错检测用软件实现,检查和方法简单、快速)。
链路层的差错检测由适配器中专用的硬件实现,采用更强的CRC方法。
循环冗余检测
特点:高效,能检查几乎所有错误,但无法纠正。广泛使用。
- 多项式表示
将二进制数据视为多项式,例如二进制串1011对应多项式 ( D ( x ) = x 3 + x + 1 ) ( D(x) = x^3 + x + 1 ) (D(x)=x3+x+1)。- 收发双方预先约定一个生成多项式 ( G ( x ) ) ( G(x) ) (G(x)),其最高次幂为 n n n
- 编码过程(发送端)
- 计算出一个r位附加比特R,添加到D的后面产生DR(d+r 比特)。DR能被生成多项式G模2运算整除,一起发送。
- 校验过程(接收端)
- 对接收到的数据多项式 ( D ′ ′ ( x ) ) ( D''(x) ) (D′′(x)) 用同样的 ( G ( x ) ) ( G(x) ) (G(x)) 做除法运算。若余数为
0,则认为数据无差错;否则判定为有误。
- 对接收到的数据多项式 ( D ′ ′ ( x ) ) ( D''(x) ) (D′′(x)) 用同样的 ( G ( x ) ) ( G(x) ) (G(x)) 做除法运算。若余数为
模2运算:加法不进位,减法不借位,即操作数按位异或 (XOR),乘以2的r次幂,即比特模式左移r个位置
例题:
假设数据D为101110,生成多项式G为1001,CRC编码为3比特,是生成多项式的位数减1。
这里用模2运输,计算CRC编码。首先将D乘以2的3次方,即可得101110000;
然后将101110000除以生成多项式1001,最后可得余数为0011,因为CRC编码只取3比特,因此为011。
因此发送方最终发送的数据为101110011。
5.3 多路访问链路和协议
广播链路
两种网络链路:
1.点对点链路:链路两端各一个节点。一个发送和一个接收。如点对点协议PPP。
2.广播链路: 多个节点连接到一个共享的广播信道。
共享广播信道是非常常见的,例如我们在公众场合说话都是属于共享信道。这种共享信道的特点是:当一个人在说话时,其他人需要安静的听,如果有多个人同时说话,会导致收听的人听不清楚,这就是产生了干扰。广播信道中的每个节点都可能发送和接收数据帧,如果多个节点同时向共享信道发送数据,会导致信道中的信号相互干扰,使数据帧不能正确接收。
如何协调多个发送和接收节点对共享广播信道的访问,相关技术即是多路访问协议(也称多址访问协议)
多路访问协议
目的:协调多个节点在共享广播信道上的传输。避免多个节点同时使用信道,发生冲突(碰撞),产生互相干扰。
冲突是指:两个以上的节点同时发送帧,使接收方收不到正确的帧(所有冲突的帧都受损丢失)。
理想的多址访问协议,对于速率为R bps的广播信道
- 当一个节点有数据发送时,它能以R bps的速率发送.
- 当有M个节点要发送数据,每个节点的平均发送速率为 R/M
- 完全分散:不需要主节点协调传输,不需要时钟、时隙同步
- 简单
信道划分协议
把信道划分为小“片” (时隙),给节点分配专用的小“片” ,设信道支持 N 个节点,传输速率是 R b/s。
时分多路访问TDMA (time division multiple access):将时间划分为时间帧,每个时间帧再划分为N个时隙(长度保证发送一个分组),分别分配给N个节点。每个节点只在固定分配的时隙中传输。
优缺点:避免冲突、公平,每个节点专用速率R/N b/s,但这也是上限,同时效率低–节点必须等待它的传输时隙。
频分多路访问FDMA (frequency division multiple access):将总信道带宽 R b/s划分为 N 个较小信道(频段,带宽为R/N),分别分配给 N 个节点。
码分多路访问CDMA (Code Division Multiple Access):每个节点分配一个唯一的编码,每个节点用它唯一的编码来对它发送的数据进行编码,允许多个节点“共存” ,信号可叠加,即可以同时传输数据而无冲突 (如果编码 是“正交化”的)
随机访问协议
不划分信道,允许冲突,能从冲突中“恢复”。
基本思想:发送节点以信道全部速率(R b/s)发送;发生冲突时,冲突的每个节点分别等待一个随机时间,再重发,直到帧(分组)发送成功,节点间没有协调者。
纯ALOHA: 非时隙Aloha: 简单,不需同步。帧一到达,立即传输。
如果与其他帧产生冲突,在该冲突帧传完之后:以概率p立即重传该帧;或等待一个帧的传输时间,再以概率p 传输该帧,或者以概率1-p 等待另一个帧的时间。冲突可能性:在t0发送的帧,和在 [t0-1,t0+1]的发送的其它帧冲突。效率:约 18%(1/(2e))。
时隙ALOHA:假设所有帧大小相同,时间被划分为相同大小的时隙,一个时隙等于传送一帧的时间,节点只能在一个时隙的开始才能传送,节点需要同步,如果一个时隙有多个节点同时传送,所有节点都能检测到冲突。过程:当节点要发送新帧,它等到下一时隙开始时传送;没有冲突,节点可以在下一时隙发送新帧;如果有冲突,节点在随后的时隙以概率p重传该帧,直到成功为止。
优点:单个活跃节点可以持续以满速率传送帧, 只需节点的时隙同步,简单。缺点是浪费时隙。效率:37%(1/(e))。
CSMA载波侦听多路访问:载波侦听:某个节点在发送之前,先监听信道。
信道忙:有其他节点正往信道发送帧,该节点随机等待一段时间(回退),然后再侦听信道。
信道空:该节点开始传输整个数据帧。
由于传播时延的存在,仍有可能出现冲突,并造成信道浪费
带冲突检测的CSMA(CSMA/CD):增加“载波侦听”和“冲突检测”两个规则。发送数据帧时,同时进行冲突检测:一旦检测到冲突就立即停止传输, 尽快重发。目的:缩短无效传送时间,提高信道的利用率。
以太网也是采用CSMA/CD机制来访问共享信道,检测到碰撞后,进行二进制指数算法回退。
二进制指数算法回退
轮流协议
通过轮流访问信道避免冲突,要发送的节点越多轮流时间越长
轮询协议:主节点按顺序邀请从节点传输,从节点仅在被邀请时发送数据。轮询指令产生额外开销;主节点故障导致全网瘫痪;节点多时有明显延时
令牌传递协议:网络中传递 “令牌”,仅持有令牌的节点可传输,传输完成后将令牌传递给下一节点。
令牌丢失或损坏导致网络瘫痪;令牌传递引入延时,节点越多效率越低。
5.4 交换局域网
局域网:Local Area Network ( LAN ),网络为一个组织所拥有,且地理范围和站点数目均有限
按拓扑结构进行分类:星形网(中央结点辐射状连接)、环形网(站与站点之间首尾相接,形成一个环,数据只能沿单方向传输。适合光纤,实时性强)、总线网(站点都连接在同一根传输线,易于扩展)、树形网和网状网(网状网络的每一个站点都与其它站点一一直接互连,能高速传输高容错,但关系复杂维护难)
计算机与局域网通过网络接口板(网卡)进行连接。网卡属于物理层,网卡驱动程序属于数据链路层。
链路层寻址和ARP
每个节点有网络层地址和链路层地址。应用层主机名如域名不一定有。
网络层地址:节点在网络中分配的一个唯一地址(IP地址)。用于把分组送到目的IP网络。长度为32比特(IPv4)。
链路层地址:又叫做MAC地址或物理地址、局域网地址。用于把数据帧从一个节点传送到另一个节点(同一网络中)。
MAC地址(LAN地址、物理地址):节点“网卡”本身所带的地址(唯一)。MAC地址长度通常6字节,地址用16进制表示,每个字节表示为一对16进制数,前三个字节向IEEE购买,后三个由厂家自行分配。网卡的MAC地址是永久的(生产时固化在其ROM里)
MAC地址识别
由“网卡”负责MAC地址的封装和识别。
发送适配器:将目的MAC地址封装到帧中,并发送。所有其他适配器都会收到这个帧。
接收适配器:检查帧的目的MAC地址是否与自己MAC地址相匹配:
匹配:接收该帧,取出数据报,并传递给上层。不匹配:丢弃该帧。
广播帧:发送给所有节点的帧,目的MAC地址需要用广播地址——全1地址:FF-FF-FF-FF-FF-FF
地址转换
过程:主机名 - ->IP地址 --> MAC地址
DNS域名系统:将主机名解析到IP地址。DNS为在因特网中任何地方的主机解析主机名。
ARP地址解析协议:将IP地址解析到MAC地址。ARP只为在同一个LAN上的节点解析IP地址。
ARP表: 局域网上的每个节点(主机、路由器)都有这个表,为某些局域网节点进行IP/MAC地址映射:< IP address; MAC address; TTL>
TTL (存活时间): 地址映射将被删除的时间(通常为20分钟)
假设同一个局域网中:主机A希望发送数据报给主机B,主机A首先查找自己维护的ARP表,看是否存在B的MAC地址,假设B的MAC地址不在A的ARP映射表中。则主机A首先广播ARP查询分组,其中包含B的IP地址,查询分组是个广播帧,即目的MAC地址是FF-FF-FF-FF-FF-FF。因此局域网中所有节点收到ARP查询分组,其余主机发现查询的不是本机的MAC地址,因此不进行回应。只有主机B收到ARP查询分组后,返回B的MAC地址给主机A,包含有B的MAC地址的帧发送给主机A(单播)。于是,主机A在自己的ARP表中缓存B主机的IP地址和MAC地址。
发送数据报到子网之外:主机A经路由器R发送数据报给主机B,假设主机A知道主机B的IP地址,假设主机A知道第一跳路由器R的IP地址(通过DHCP协议),假设主机A知道路由器R的MAC地址(通过ARP协议)。主机A构建IP数据报,源地址是A的IP地址,目的地址是B的IP地址主机A构建链路层数据帧,目的MAC地址是路由器左边端口的MAC地址(靠近A的那一端)。数据帧从主机A发送到路由器R,路由器R收到数据帧,抽取出数据报递交到IP层。路由器R转发数据报,源地址为A的IP地址,目的地址为B的IP地址,路由器R将该数据报封装成链路层帧,目的MAC地址为主机B的MAC地址
以太网Ethernet
以太网技术是最著名的有线局域网技术,常见有两种物理拓扑结构,常用5类和超5类双绞线。
总线型:一直流行到90年代中期,所有节点都属于相同的冲突域
星形:目前仍然非常流行,星形结构的中心是交换机,每个端口运行一个独立的以太网协议,节点相互之间发送数据帧不发生碰撞,每个端口对应的网段是一个独立的碰撞域。
以太网链路层技术:数据封装(帧同步、帧定界;地址确定;错误检测机制),媒体访问管理(媒体分配(避免冲突),冲突解决(冲突处理))
以太网帧结构
前同步码:“前7字节是“10101010”,最后一个字节是“10101011”。使接收方和发送方的时钟同步,接收方一旦收到连续的8字节前同步码,可确定有帧传过来。前同步码是“无效信号”,接收方收到后删除,不向上层传。CRC的校验范围不包括前同步码。
源、目的MAC地址(各6字节):适配器B只接收目的地址与其MAC地址匹配或广播地址的帧,并将数据字段的内容传递给网络层。否则,丢弃该帧。
类型:主要是支持以太网中的多种网络层协议的复用的,绝大多数是指IP协议
数据字段:携带网络层传来的IP数据报,若IP数据报超过1500字节,必须将该数据报分段。最小长度是46字节:如果IP数据报小于46字节,必须填充为46字节。接收方网络层去除填充内容。
以太网提供的是不可靠的无连接服务。无连接:无需握手。不可靠:收到正确帧,不发确认帧;收到出错帧,丢弃该帧,不发否定帧。不重发出错帧。使用无时隙的CSMA/CD协议(二进制指数回退)
链路层交换机
交换机是属于链路层的设备,其主要作用是存储转发数据帧。对于到达交换机的数据帧,交换机首先检查其目的MAC地址,然后根据MAC地址,有选择的将数据帧转发到一个或多个输出链路;如果输出链路是一个共享网段,将使用CSMA/CD来访问共享链路。第二个特点是透明,这里的透明是指的当一个主机向另一个主机发送数据帧时,它并不会知道某个交换机会收到这个数据帧,并将其转发到另一个节点。交换机无需手工配置,即插即用。
交换机可以支持多个节点同时传输数据帧。每个主机由单独的链路与交换机端口相连,因此交换机每个端口对应的链路和主机是一个独立的碰撞域。交换机对于收到的数据帧可进行缓存。
机制:识别目的MAC地址,根据交换表进行端口选择。识别源MAC地址更新交换表。
自学习机制:每当交换机收到一个数据帧时,交换机会学习发送主机的位置及进入的局域网段和到达端口,并在转发表中进行记录。
当交换机收到数据帧进行查表转发的过程:
1.记录到达链路和发送主机的MAC地址
2.使用数据帧的目的MAC地址,在转发表中检索
3.如果在转发表条目中找到对应的MAC地址
4.执行: 如果 目的MAC地址对应的端口与数据帧的达到端口相同 则 丢弃该数据帧 否则 转发该数据帧到条目指定的端口
5.否则,向除到达端口之外的所有端口转发(flood,泛洪)。目标主机如果在某个端口下,就会响应,发送一个数据帧回来。这时候交换机收到响应帧,会学习源 MAC(即目标主机的 MAC)和对应的端口。
例题
交换机的交换方式
存储转发(缓存整个帧后再转发),具有差错检测功能,转发时延较大,适用于出错率高的链路。
快速分组又称直通交换(识别出目的地址直接转发),不具有差错检测功能,转发时延较小,适用于时延要求高,出错率低的链路。
三层交换机
传统的交换技术在OSI模型的第二层即数据链路层做交换,而三层交换技术就是在第三层即网络层做交换,本质上是二层交换技术+三层转发技术,三层交换机就是“二层交换机+基于硬件的路由器”
工作原理
发送站点A在开始发送时,把自己的IP地址与B站的IP地址比较,判断B站是否与自己在同一子网内。
若目的站B与发送站A在同一子网内,则进行二层的转发。
若两个站点不在同一子网内,则发送站A要向“缺省网关”发出ARP请求,请求获得B的MAC地址。
如果三层交换机知道B的MAC地址,则向A回复B的MAC地址。否则三层交换机根据路由信息向B站广播一个ARP请求,B站得到此ARP请求后向三层交换机回复其MAC地址,三层交换机将B站的MAC地址保存到二层交换引擎的MAC地址表中,并回复给发送站A。
A直接用B的MAC地址封装数据帧,三层交换机接收到数据后直接进行二层交换。
VLAN
基于端口的VLAN: 利用交换机内置的管理软件,将端口分组,使得一个单独的交换机像多个交换机那样工作。分属不同的虚假交换机端口间有流量隔离。
第六章 套接字编程
6.1 网络编程基础
服务器: 总是打开的主机,具有固定的、众所周知的IP地址,主机群集常被用于创建强大的虚拟服务器
客户机:同服务器端通信,可以间断的同服务器连接,可以拥有动态IP地址,客户机相互之间不直接通信
网络字节顺序
采用大端排序方式,总是从低位地址开始传输。发送数据包时,程序将主机字节序转换为网络字节序;接受收数据包时,则将网络字节序转换为主机字节序。
数据结构对齐
是由编译器对代码进行处理来实现,防止内存的二次访问,一次性取出所需数据。每个特定平台的编译器都有自己的默认“对齐系数” 。
结构体对齐规则:
结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
结构体每个成员相对结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节;
结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节
接口协议
1.TCP/IP协议存在于OS中,网络服务通过OS提供
2.TCP/IP要尽量避免让接口使用某一个厂商的OS中特有的特征(而其他厂商没有)
3.TCP/IP和应用程序之间的接口应该不精确指明:
①不规定接口的细节 ②只建议需要的功能集 ③允许系统设计者选择有关API的具体实现细节
提供了灵活性和容错能力,但移植性差
POSIX表示可移植操作系统接口,源代码级别的软件可移植性
系统调用
为安全考量,诸如I/O操作等特权指令被限制在内核态模式执行,系统调用使得应用程序从操作系统获得服务。
open:返回文件描述符(file descriptor)
int desc;
desc = open(“filename”, O_RDWR, 0);
read:利用上述文件标识符
read(desc, buffer,128);
write:与open, read类似
close:撤销标识符并释放资源
close(desc);
将Linux I/O用于TCP/IP
1.扩展文件描述符,可用于网络通信 2.扩展read,write,可用于操作网络标识符
3.额外功能的处理,通过增加新系统调用实现:
①指明本地和远端的端口,远程IP地址 ②使用TCP还是UDP
③启动传输还是等待传入连接 ④可以接受多少传入连接 ⑤传输UDP数据
Socket
定义:
Socket是操作系统提供的协议操作接口,而非协议本身。它是本地应用程序创建的通信接口,遵循Client/Server模式,允许应用进程通过传输层服务,跨网络发送或接收消息。
Socket的分类与工作模式
按角色分类:
- 被动套接字:等待传入连接(如服务器套接字)。
- 主动套接字:发起连接(如客户端套接字)。
核心特性:
- 端到端地址在创建时不指定,使用时需明确(如TCP/IP需指定协议端口号和IP地址)。
TCP/IP协议族中的Socket关键概念
- 协议族与地址族:
- PF_INET:TCP/IP协议族(Protocol Family)。
- AF_INET:TCP/IP地址族(Address Family)。
- 设计逻辑:早期设计认为一个协议族可能对应多种地址形式,因此API中将PF(创建socket时使用)与AF(绑定/连接时使用)分开。但实际应用中,一个PF仅对应一个AF,二者可混用。
- 支持的通信协议(地址族):
- Unix:Unix系统内部协议。
- INET(AF_INET):IPv4协议。
- INET6(AF_INET6):IPv6协议。
Socket类型与对应通信服务
| Socket类型 | 通信特性 | 对应传输层协议 |
|---|---|---|
| SOCKET_DGRAM | 双向不可靠数据报(无连接) | UDP |
| SOCKET_STREAM | 双向可靠数据流(面向连接) | TCP |
| SOCKET_RAW | 访问低级协议或物理网络接口 | 原始套接字(如IP层) |
地址结构
Socket 通用地址结构 sockaddr的局限
- Socket 的本质与编址需求
Socket 是传输层/网络层的编程接口,由于不同传输层/网络层实现(如 IPv4、IPv6、本地通信等)采用不同的编址方案,因此需要定义通用地址结构来适配多种场景。 - sockaddr 结构的局限性
通用地址结构sockaddr虽为适应多编址方案而设计,但实际通用性有限: 对于AF_INET6(IPv6)或AF_LOCAL(本地套接字)等类型的 Socket 地址,sockaddr结构仅能标识地址类型,无法完整描述地址细节(如具体IP地址、端口等)。
地址转换函数的作用
- 地址表示的矛盾
人们习惯用点分十进制字符串(如202.112.14.151)表示 IP 地址,但此类字符串本质上非数值类型,无法直接用于 Socket 编程中的底层网络通信(底层接口需数值型地址)。 - 转换的必要性
因此,在 Socket 编程时,需通过地址转换函数(如inet_pton、inet_ntop等)实现字符串地址与数值地址的相互转换,确保程序能正确解析和使用网络地址。
int inet_pton(int family, const char *src, void *dst)
返回:1-成功,0-输入无效,-1:出错
将src指向的字符串转换成二进制地址数值放到dst中。
const char *inet_ntop(int family, const void *src, char *dst, size_t cnt)
返回:指向结果的指针--成功,NULL-出错
和pton做相反的操作。
family参数可以是AF_INET,也可以是AF_INET6。
如果长度参数cnt太小,无法容纳表达式格式结果,则返回一个空串。另外,目标指针dst调用前必须先由调用者分配空间。
6.2 Socket套接字与循环服务器
简单TCP循环服务器Socket编程基本步骤⭐
服务器端:创建套接字,绑定套接字,设置套接字为监听模式,进入被动接受连接状态,接受请求,建立连接,读写数据,终止连接
客户端:创建套接字,与远程服务器建立连接,读写数据,终止连接
简单UDP循环服务器Socket编程基本步骤
服务器端:建立UDP套接字;,绑定套接字到特定地址;,等待并接收客户端信息;,处理客户端请求;,发送信息回客户端;,关闭套接字;
客户端:建立UDP套接字;,发送信息给服务器;,接收来自服务器的信息;,关闭套接字
Socket 核心函数用法整理
#include <sys/socket.h>
1. int socket (int family, int type, int protocol);
returns: non-negative descriptor if OK, -1 on error
功能:创建套接字,返回描述符。
参数:
family:协议族(如 AF_INET 表示 TCP/IP)。
type:服务类型(SOCK_STREAM 为 TCP,SOCK_DGRAM 为 UDP)。
protocol:协议字段,通常为 0。
2. int bind (int sockfd, const struct sockaddr *myaddr, socklen_t addrlen);
returns: 0 OK, -1 on error
功能:绑定本地地址(IP + 端口)到套接字。
参数:
sockfd:套接字描述符。
myaddr:本地地址结构体(如 sockaddr_in)。
addrlen:地址长度。
3. int listen (int sockfd, int backlog);
returns: 0 OK, -1 on error
功能:将套接字设为被动监听状态,准备接收连接。
参数:
sockfd:套接字描述符。
backlog:连接队列最大长度。
4. int accept (int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);
returns: non-negative descriptor if OK, -1 on error
功能:接受客户端连接,创建新套接字用于数据传输。
参数:
sockfd:监听套接字描述符。
cliaddr:客户端地址结构体指针。
addrlen:地址长度指针。
5. int connect (int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);
returns: 0 if OK, -1 on error
功能:客户端主动连接远程服务器。
参数:
sockfd:套接字描述符。
servaddr:服务器地址结构体。
addrlen:地址长度。
6. int send(int sockfd, const void * data, int data_len, unsigned int flags)
返回值:成功返回发送字节数,失败返回 -1。
功能:在 TCP 连接上发送数据。
参数:
sockfd:套接字描述符。
data:数据指针。
data_len:数据长度。
flags:标志位(通常为 0)。
7. int sendto(int sockfd, const void * data, int data_len, unsigned int flags, struct sockaddr *remaddr, int remaddr_len)
返回值:成功返回发送字节数,失败返回 -1。
功能:在 UDP 上发送数据报,需指定目标地址。
参数:
sockfd:套接字描述符。
data:数据指针。
data_len:数据长度。
flags:标志位(通常为 0)。
remaddr:目标地址结构体。
remaddr_len:地址长度。
8. int recv(int sockfd, void *buf, int buf_len,unsigned int flags);
返回值:成功返回接收字节数,失败返回 -1。
功能:在 TCP 连接上接收数据。
参数:
sockfd:套接字描述符。
buf:接收缓冲区指针。
buf_len:缓冲区大小。
flags:标志位(通常为 0)。
9.int recvfrom(int sockfd, void *buf, int buf_len, unsigned int flags, struct sockaddr *from, int fromlen); 返回值:成功返回接收字节数,失败返回 -1。
功能:在 UDP 上接收数据报,获取发送方地址。
参数:
sockfd:套接字描述符。
buf:接收缓冲区指针。
buf_len:缓冲区大小。
flags:标志位(通常为 0)。
from:发送方地址结构体指针。
fromlen:地址长度指针。
10. Int close(int sockfd);
返回值:成功返回 0,失败返回 -1。
功能:关闭套接字(释放文件描述符)。
参数: sockfd:套接字描述符。
以下示例展示了 TCP 服务器/客户端和 UDP 通信的完整流程:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT_TCP 8080
#define PORT_UDP 9090
#define BUFFER_SIZE 1024
// TCP 服务器示例
void tcp_server() {
int sockfd, newsockfd;
struct sockaddr_in server_addr, client_addr;
socklen_t client_len = sizeof(client_addr);
char buffer[BUFFER_SIZE];
// 创建 TCP 套接字
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
// 填充服务器地址
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(PORT_TCP);
// 绑定地址
if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
// 监听连接
if (listen(sockfd, 5) < 0) {
perror("listen failed");
exit(EXIT_FAILURE);
}
printf("TCP Server listening on port %d...\n", PORT_TCP);
// 接受客户端连接
if ((newsockfd = accept(sockfd, (struct sockaddr *)&client_addr, &client_len)) < 0) {
perror("accept failed");
exit(EXIT_FAILURE);
}
printf("TCP Client connected: %s:%d\n",
inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
// 接收数据
int recv_bytes = recv(newsockfd, buffer, BUFFER_SIZE, 0);
if (recv_bytes > 0) {
buffer[recv_bytes] = '\0';
printf("TCP Received: %s\n", buffer);
}
// 发送响应
const char *response = "Hello from TCP server!";
send(newsockfd, response, strlen(response), 0);
// 关闭套接字
close(newsockfd);
close(sockfd);
}
// TCP 客户端示例
void tcp_client() {
int sockfd;
struct sockaddr_in server_addr;
char buffer[BUFFER_SIZE];
// 创建 TCP 套接字
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
// 填充服务器地址
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT_TCP);
// 转换 IP 地址(示例使用本地回环地址)
if (inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr) <= 0) {
perror("invalid address");
exit(EXIT_FAILURE);
}
// 连接服务器
if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("connect failed");
exit(EXIT_FAILURE);
}
// 发送数据
const char *message = "Hello from TCP client!";
send(sockfd, message, strlen(message), 0);
// 接收响应
int recv_bytes = recv(sockfd, buffer, BUFFER_SIZE, 0);
if (recv_bytes > 0) {
buffer[recv_bytes] = '\0';
printf("TCP Received: %s\n", buffer);
}
// 关闭套接字
close(sockfd);
}
// UDP 通信示例
void udp_communication() {
int sockfd;
struct sockaddr_in server_addr, client_addr;
socklen_t client_len = sizeof(client_addr);
char buffer[BUFFER_SIZE];
// 创建 UDP 套接字
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
// 填充服务器地址(用于接收)
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(PORT_UDP);
// 绑定地址
if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
printf("UDP Server listening on port %d...\n", PORT_UDP);
// 接收 UDP 数据报(同时获取客户端地址)
int recv_bytes = recvfrom(sockfd, buffer, BUFFER_SIZE, 0,
(struct sockaddr *)&client_addr, &client_len);
if (recv_bytes > 0) {
buffer[recv_bytes] = '\0';
printf("UDP Received from %s:%d: %s\n",
inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), buffer);
}
// 发送 UDP 响应
const char *response = "Hello from UDP server!";
sendto(sockfd, response, strlen(response), 0,
(struct sockaddr *)&client_addr, client_len);
// 关闭套接字
close(sockfd);
}
int main() {
// 启动 TCP 服务器(单独进程或线程)
pid_t pid = fork();
if (pid == 0) {
tcp_server();
exit(EXIT_SUCCESS);
}
// 客户端执行 TCP 连接和 UDP 通信
sleep(1); // 等待服务器启动
tcp_client();
// UDP 通信(客户端与服务器通信)
udp_communication();
// 等待服务器进程结束
wait(NULL);
printf("All operations completed.\n");
return 0;
}
6.3 多进程、多线程并发服务器设计
多进程并发服务器模型⭐
迭代服务器的特点:多用户的情况下,连接建立后,若没有accept,连接存放在listen函数队列。accept 从已完成队列的对头摘取新套接字。对客户端的服务是一个串行的过程
采用多进程的方式引入并行。目的:使得每个客户端都能够得到一个进程的服务
signal函数:使用方法简单,但并不属于 POSIX 标准
函数原型:sig_t signal (int signum, sighandler_t handler)
sigaction 函数:POSIX 标准定义的信号处理接口
函数原型:int sigaction (int signum, const struct sigaction *act, struct sigaction *oldact)
#include <sys/wait.h>
pid_t wait(int *status);
pit_t waitpid(pid_t pid,int *status,int options);
两个函数均为若成功,返回进程ID,若出错则返回-1
多线程
POSIX线程库——Pthreads是POSIX的线程标准,定义了创建和操纵线程的一套API。
线程创建pthread_create( ) 线程等待pthread_join( ) 获取自己的线程ID pthread_self( )
线程分离pthread_detach( ) 线程终止pthread_exit()
此外,还有pthread_kill(), pthread_yield(), pthread_attr_init(), pthread_attr_destroy()等
#include <sys/socket.h>
int shutdown(int sockfd, int how);
功能:可以按照要求关闭连接,且不管有多个文件描述符指向同一个连接,只要调用shutdown去操作了其中某个描述符,连接就会被立即断开。shutdown 可以有选择的终止某个方向的数据传送或者数据传送的两个方向。shutdown直接使得该套接字不可用,而close不能保证(套接字引用计数减为0才关闭)
返回值:成功:返回0,失败:返回-1
6.4 I/O模型以及基于I/O复用的并发服务器设计
POSIX定义这两个术语如下:
同步I/O操作引起请求进程阻塞,知道I/O操作完成;异步I/O操作不引起请求进程阻塞;
IO的两个阶段都没有被阻塞,才能被称为异步IO
五种I/O 模式
①阻塞 I/O :数据没有到之前程序会一直等待,Linux下的I/O操作默认是阻塞I/O,即open和socket创建的I/O都是阻塞I/O
②非阻塞 I/O:可以通过fcntl或者open时使用O_NONBLOCK参数,将fd设置为非阻塞的I/O。对每次请求,内核都不会阻塞,会立即返回;当没有数据的时候,会返回一个错误
③I/O 多路复用:为了避免CPU空转,使用一个代理(select/poll/epoll…)同时观察许多流的I/O事件,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有I/O事件时,就从阻塞态中醒来,于是我们的程序就会轮询一遍所有的流。通常需要非阻塞I/O配合使用
④信号驱动 I/O:信号驱动的IO在进程开始的时候注册一个信号处理的回调函数,进程继续执行,当信号发生时,即有了IO的时间,这里即有数据到来,利用注册的回调函数将到来的数据用recvfrom()接收到。
⑤异步 I/O:异步IO与前面的信号驱动IO相似,其区别在于信号驱动IO当数据到来的时候,使用信号通知注册的信号处理函数,而异步IO则在数据复制完成的时候才发送信号通知注册的信号处理函数
更多推荐
所有评论(0)