计算机网络CS 168
CS168
Introduction
Introduction to the Internet
1. 什么是互联网(What is the Internet)
互联网是用于全球设备间数据传输的基础设施(包括硬件和软件)。
强调互联网(Internet) 与万维网(World Wide Web) 不是同一概念:Web 是构建在互联网之上的应用(如浏览器访问的网站),而互联网还支持非 Web 应用(如 Zoom、在线游戏、物联网设备)。
2. 互联网为什么有趣(Why is the Internet Interesting)
互联网不是一种全新的网络技术,而是连接不同现有网络的新问题。
它带来了与传统计算机科学领域不同的挑战:
没有形式化模型(不像理论领域);
没有可量化的性能基准(不像硬件领域);
代码不仅要“能跑”,还要扩展到数十亿用户,并考虑运营商之间的商业关系。
互联网设计强调权衡(trade-offs),而非最优解,更注重实用性和目标平衡。
3. 互联网是联邦制的(The Internet is Federated)
互联网由多个独立运营商(ISP)组成,它们必须互操作才能实现全球连接。
联邦制带来挑战:
竞争企业必须合作,即使不愿共享信息;
协议设计需兼顾技术和商业激励;
创新受限于共同语言(协议),任何新功能必须兼容已有标准。
4. 互联网是可扩展的(The Internet is Scalable)
联邦制使互联网规模巨大,且技术多样(无线、光纤等),能力差异大(从家庭小带宽到海底大容量电缆)。
规模带来设计挑战:
系统必须支持海量用户和应用(需求不同,甚至存在恶意行为);
必须异步操作,因为光速限制导致信息传输延迟;
单个消息可能涉及多个组件,故障是常态,且难以快速感知;
互联网是首个大规模考虑故障设计的系统,其思想后来被其他领域借鉴。
5. 协议(Protocols)
协议是本节重点,定义实体间如何交换信息(格式和响应规则)。
举例:Alice 和 Bob 的交互需定义语法(如何用二进制表达请求)和语义(何时请求、如何响应)。
协议设计需考虑效率、边界情况、恶意行为等。
许多互联网协议以 RFC(Request For Comments) 形式发布,由不同标准组织(如 IEEE 关注底层电气工程,IETF 关注互联网)负责。
Layers of the Internet
1. 分层结构的总体思路
采用自底向上的方式构建互联网,从最基础的信号传输开始,逐步组合成更复杂的系统。
使用邮政系统作为类比(邮递员 → 本地邮局 → 不同城市邮局 → 全球邮网),帮助理解互联网如何逐层扩展。
强调模块化与抽象:每一层都建立在下一层的基础上,并为上一层提供服务。这种分层设计使得互联网可扩展、可维护,并允许不同层独立创新。
2. 各层详解
Layer 1:物理层(Physical Layer)
负责在物理介质上传输比特(0和1)。
技术包括:电线上的电压、无线射频、光纤中的光脉冲等。
类比:邮政系统中的“运输方式”(邮递员、马车、卡车等)。
Layer 2:链路层(Link Layer)
负责在本地网络(如局域网 LAN)中连接两台机器。
将比特组合成数据帧(frames),并定义帧的起止位置。
处理共享介质上的冲突问题(如多人同时使用同一线路)。
类比:邮政系统中连接同一城镇内各家各户的邮路。
Layer 3:网络层(Internet Layer)
核心任务:将不同的本地网络连接起来,形成全球互联网(网络的网络)。
引入路由器/交换机(routers/switches),负责在不同网络间转发数据包。
关键抽象:
数据包(packet):独立传输的小块数据。
尽力而为服务模型(best-effort):网络尽力传送数据,但不保证送达,也不通知失败。
后续章节会深入讲解路由(routing)和拥塞控制(congestion control)。
类比:引入“邮局”连接不同城镇,邮局之间互相转发信件。
Layer 4:传输层(Transport)
解决 Layer 3 的两个问题:
数据包大小有限 → 将大文件拆分为多个包;
尽力而为不保证送达 → 实现丢包重传、排序、流量控制等。
提供可靠的数据流(flow/stream)抽象,让应用不再关心单个包,而是面向端到端的数据流。
典型协议:TCP(提供可靠传输),UDP(不提供可靠但更轻量)。
Layer 7:应用层(Application)
支持各种具体应用(Web、Email、视频会议等)。
应用层协议直接为用户服务,例如 HTTP、SMTP 等。
强调互联网是通用通信平台,不是为某类应用定制的,因此不同应用可以共享同样的底层基础设施。
3. 关于层号跳跃(5、6层)
原本 OSI 模型包含会话层(Session,5)和表示层(Presentation,6),但在现代互联网中已被淘汰,其功能被应用层吸收或不再使用。
4. 分层带来的优势
独立创新:不同层可以各自发展(如物理层升级光纤,不影响上层应用)。
局部管理:每个本地网络可自行决定链路技术,只需遵循统一的 Layer 3 协议即可互联。
清晰接口:层与层之间通过标准接口交互,降低系统复杂度。
5. 关键设计思想提炼
网络的网络:互联网由无数独立运营的本地网络互联而成。
端主机与路由器区分:端主机(如手机、服务器)是通信的终点;路由器只负责转发数据,不产生或消费数据。
尽力而为 + 上层弥补:网络层保持简单高效,复杂功能(如可靠性)由传输层在终端实现(体现端到端原则)。
Header
1. 为什么需要头部(Why Do We Need Headers?)
问题:如果直接把数据(如一张图片的比特)扔到网络上,交换机/路由器不知道该如何处理这些比特。
类比:写信时,不能只写内容,必须把信装进信封,并在信封上写上收件人地址等信息,邮局才知道如何投递。
对应到网络:每个数据包必须附加元数据(metadata),即头部(header),用于告诉网络设备如何处理这个包。
头部 vs. 载荷(Payload):
头部:附加的控制信息(如地址),供网络基础设施使用。
载荷:实际要传输的用户数据(如文件内容)。
职责分离:网络设备只读头部,不读载荷;接收端应用只关心载荷,不关心头部(但发送端需要生成头部)。
2. 头部需要标准化(Headers are Standardized)
头部可以看作用户(端主机)与网络基础设施之间的 API。
全网必须统一格式:如果某操作系统改了头部格式,其他设备将无法理解该数据包。
设计困难:一旦标准化并部署,改动极难(需要全球所有设备同步更新),因此标准组织会花很长时间谨慎设计。
3. 头部应该包含什么信息(What Should a Header Contain?)
必备:目的地址(destination address)——告诉网络将包发往何处。
常用但非必需:
源地址(source address):便于接收方回复。
校验和(checksum):检测传输过程中是否损坏。
包长度(length):因为数据包大小可变。
不同层可能有不同的头部内容,后续会详细展开。
4. 多层头部(Multiple Headers)
通过邮政系统类比说明多层封装:
老板写内部信件 → 秘书装进信封(写收件人姓名)→ 邮务员装进纸箱(写公司地址)→ 放入运输车(物理运输)。
每加一层,就包裹一个新的头部;每解一层,就剥去一个头部。
每一层只处理自己的头部,就像秘书只读信封上的名字,邮务员只读纸箱上的地址。
对等层通信(Peer-to-Peer Communication):
发送方的某一层与接收方的同一层“逻辑通信”,该层的协议只对这两端的同层实体有意义。
例如:秘书A写的信封是给秘书B看的,不是给邮差或老板看的。
5. 地址与命名(Addressing and Naming)
地址是告诉网络主机在网络中位置的值。
不同层使用不同的寻址方案:
人类可读名称:如 www.google.com(域名)。
IP地址:如 74.124.56.2,与位置相关,可能随服务器移动而改变。
MAC地址:硬件地址,全球唯一且不会改变。
这些不同形式的地址在不同层使用,彼此独立。
6. 主机和路由器中的层次处理(Layers at Hosts and Routers)
端主机(如电脑、手机):需要实现所有层(1~7),因为要从应用层数据一直封装到物理层发送,并反向解析接收到的数据。
路由器:只需要实现低三层(物理层、链路层、网络层):
路由器要接收比特(L1)、在链路上传输帧(L2)、并根据网络层头部(L3)进行转发(forwarding)。
路由器不需要传输层(L4)和应用层(L7),因为它不关心数据是否可靠到达,也不运行浏览器等应用。
7. 多层头部在主机和路由器中的处理过程(结合类比)
类比:信件从公司A出发,经过多个邮局,每个邮局:
打开外层箱子 → 看到内部信封(L3头部)→ 决定下一站 → 装入新箱子(新L2/L1头部)→ 送出。
**每一层只负责封装“自己这一层”的头部,它根本不关心上一层封装了什么名字的头。**
邮局从不打开信封(即不解析L4及以上头部)。
实际网络中:
发送端主机:从上到下逐层添加头部(L7→L4→L3→L2→L1),然后发送。
沿途每个路由器:解析到L3头部,读取目的地址,决定下一跳;然后重新封装新的L2/L1头部,转发出去。路由器不触碰L4及以上头部。
这里我一直有个疑问,为什么要重新封装,仔细想了想后终于明白了,**重新封装成已经抵达的那个MAC地址**;比如你现在从电脑A发到路由器1 但是路由器的MAC地址跟电脑A的不一样 所以才需要覆盖旧的MAC地址,上新 的MAC地址上去
接收端主机:从下到上逐层剥除头部(L1→L2→L3→L4→L7),最终获得应用数据。
关键优势:每一跳可以使用不同的L2/L1协议(例如第一段用有线,第二段用无线),只要L3协议统一即可。
8. 总结要点
头部是网络通信的“信封”,承载控制信息,是协议交互的核心。
分层封装与解封装是互联网协议栈工作的基本方式。
对等层通信使得各层独立,简化设计和实现。
路由器只处理到L3,体现了“简单核心 + 智能边缘”的设计哲学(复杂功能如可靠传输由端主机实现)。
这种设计允许异构网络互联,并支持底层技术的独立演进。
Network Architecture
1. 设计范式概述(Design Paradigms)
之前是自底向上看互联网(从物理层搭建到应用层),现在改为自上而下分析其顶层设计哲学。
这些设计是多年前做出的,当时互联网远未达到如今的规模。它们并非唯一可能的设计,至今仍存在争议(例如联邦制 vs. 集中式 SDN)。
早期设计(如“傻瓜式”交换机)可能未考虑现代安全问题(如 DDoS 攻击)。
2. 窄腰(Narrow Waist)
含义:在协议栈的第3层(网络层,即IP协议),只有一个核心协议——IP。
图示表现:协议栈呈“沙漏”形状,腰部(IP层)最窄。
重要性:全网所有设备必须统一使用 IP,才能实现全球互联。这是互联网能够连接不同网络的基础。
允许多样性:在 IP 之上可以有多种传输层协议(如 TCP、UDP),之下可以有多种链路层技术(如 Ethernet、Wi-Fi),但IP 是大家必须共同遵守的“通用语言”。
3. 解复用(Demultiplexing)
定义:设备根据头部信息,决定将收到的数据包交给哪一个上层协议或应用程序处理的过程。
如何实现:每一层的头部都包含一个标识字段,指示下一层应该由谁处理。
L2 头部 → 指示 L3 协议(如 IPv4、IPv6)
L3 头部(IP) → 指示 L4 协议(如 TCP、UDP)
L4 头部(TCP/UDP) → 包含端口号(port),由操作系统将数据交给对应的套接字(socket)和应用程序。
注意区分两个“端口”:
物理端口:交换机上实际插网线的接口。
逻辑端口:L4 头部中的数字编号,用于区分同一主机上的不同应用程序(如 80 是 HTTP,443 是 HTTPS)。
套接字(Socket):操作系统提供的机制,连接应用程序和网络协议栈,通过端口号关联。
4. 端到端原则(End-to-End Principle)
这是本章最核心、最具哲学性的论点,解答了“为什么路由器只处理到 L3,而复杂功能(如可靠性)由端主机实现?”
端到端也就是 **"中间节点(路由器)不参与数据完整性校验,只有发送方和接收方的主机来确认数据是否正确到达**
核心论点:
某些功能(如可靠传输)必须在端到端的基础上实现,才能保证正确性。 在中间网络节点(路由器)实现这些功能,既不是必要的,也不足以保证正确,反而会增加复杂性和成本。
通过“可靠性”案例对比两种方案:
方案A:在网络中实现可靠传输
方案B:端到端实现可靠传输(实际采用)
做法:每个路由器负责确保下一跳收到数据,丢失则重传。
路由器只做尽力而为(best-effort),端主机自己检查是否收到全部数据,丢失则重传。
问题:
如果某个路由器有 bug 丢包,端主机无法干预,无法保证最终可靠性。 端主机掌握控制权,即使有 bug 也可以自己修复。
结论:网络内部的可靠性无法完全保证正确,端主机最终还是要做端到端检查,因此多此一举。 这就是互联网实际采用的方式——IP 只提供尽力而为,TCP 在端主机实现可靠传输。
端到端原则的广义延伸:
不仅适用于可靠性,也适用于其他领域,如安全(加密):应该在端主机加密,而不是在网络中间节点加密。
不是绝对定理,而是指导原则:有时在网络中增加部分功能(如无线链路的重传)可以提升性能,但最终的正确性仍由端到端保证。
Clark 的原话总结:
“某项功能只有借助端点的知识和帮助才能完整且正确地实现,因此在通信系统本身中提供该功能是不可能的。有时,通信系统提供一个不完整的版本可能作为性能增强手段。”
Designing Resource Sharing
1. 用什么理念来决定"建多少路"?(统计复用)
问题:网络带宽有限,用户需求忽高忽低(你睡觉时不用网,醒着时才用)。
策略:采用统计复用。不按"所有人峰值加起来"的天文数字去建网(那样太浪费),而是按"所有人同时使用的平均值"去建。
风险:万一大家恰好同时达到峰值,网络就会堵车(丢包/延迟),但互联网选择了接受这个偶尔的风险,换取日常的高效利用。
2. 用什么机制来分配"现有的路"?(电路交换 vs. 分组交换)
有了有限的路(带宽),怎么分给当前要用的数据流?
电路交换(打电话模式):先预约,再使用。发数据前,先沿途跟所有路由器打招呼"我要占10M带宽",全同意了才发。发完再挨个通知"释放"。
分组交换(寄快递模式):不预约,直接发。每个数据包自己写个目的地,直接扔进网络。每个路由器看到包就独立决定往哪扔,不管这个包属于哪个"流",也不管之前有没有预约。
| 维度 | 电路交换(预约) | 分组交换(随发) |
| --- | --- | --- |
| **效率** | 差。预约了12M却只用了5M,**浪费带宽**;且建立/拆除连接有**额外耗时**。 | 好。有数据才占带宽,**不浪费**,没有建立连接的延迟。 |
| **应对故障** | 极差。中间一个路由器坏了,**几百万条预约**要同时重新协商,瞬间瘫痪。 | 好。路由器坏了,数据包**自动绕路**,两端主机毫无感知。 |
| **实现复杂度** | 极复杂。需要**百万台路由器状态达成一致**(类似Paxos共识算法),极其困难。 | 简单。路由器**无状态**,只负责转发,不用跟别人协商。 |
| **业务模型** | 对开发者友好(有带宽保证),适合运营商收钱。 | 对开发者不友好(没保证),但应用层(如视频App)自己适应了。
Links
1. 链路的三个基本属性
| 属性 | 含义 | 管道类比 | 单位 |
| --- | --- | --- | --- |
| **带宽(Bandwidth)** | 每秒能往链路上塞多少比特 | 管道的**宽度** | bps(比特/秒) |
| **传播延迟(Propagation Delay)** | 一个比特从链路一端走到另一端需要多长时间 | 管道的**长度** | 秒(毫秒/微秒) |
| **带宽-延迟积(BDP)** | 带宽 × 传播延迟 = 链路上任意时刻"在途"的比特总数 | 管道的**容量**(装满水时有多少水) | 比特 |
2. 数据包在链路上的总延迟 = 两项之和
总延迟 = 传输延迟(Transmission Delay) + 传播延迟(Propagation Delay)
传输延迟 = 数据包大小 ÷ 带宽(把包的所有比特"推"到链路上需要多久)
传播延迟 = 信号在介质上跑的时间(光/电信号从这头跑到那头需要多久)
关键区别:传输延迟取决于"包有多大、带宽有多宽";传播延迟取决于"物理距离有多远"。两者独立,互不影响。
3. 管道图(Pipe Diagram)——把时间"冻住"看链路
这是教材教的一种可视化工具,用来直观理解链路:
把链路画成一个矩形管道,宽度 = 传播延迟,高度 = 带宽,面积 = BDP(容量)
数据包在管道里画成一个矩形块:
包的高度 = 每一时刻能推进去的比特数(由带宽决定)
包的宽度 = 传输延迟(把整个包推进去需要多少时间)
非直观但关键的结论:包的"宽度"等于传输延迟,而不是包的大小。带宽越大,包越"矮胖"(推进去快,宽度窄)。
4. 过载与排队(Overloaded Links & Queuing)
现实中的交换机/路由器会同时收到多个包,但出链路一次只能发一个:
| 情况 | 描述 | 后果 |
| --- | --- | --- |
| **瞬时过载(Transient Overload)** | 偶尔两个包同时到达,但长期来看容量够 | 交换机**排队**(Queue),一个先发,一个等一会儿 |
| **持续过载(Persistent Overload)** | 长期来看入流量 > 出链路容量 | 队列填满后,**只能丢包(Drop)** |
排队带来的后果:总延迟公式要加上一项 → 总延迟 = 传输延迟 + 传播延迟 + 排队延迟
本文来自博客园,作者:Alaso_shuang,转载请注明原文链接:https://www.cnblogs.com/Alaso687/p/22911317

浙公网安备 33010602011771号