3天:OSI七层模型

第3天:OSI七层模型

“网络协议就像流水线,每一层都有自己的分工。”

📚 今日目标

  • 理解什么是OSI七层模型
  • 掌握每一层的作用
  • 理解数据封装和解封装过程
  • 编写程序演示协议分层

🎯 为什么要分层?

生活中的例子:快递系统

想象你要给上海的朋友寄一本书:

你写信 ────────────────────────────> 朋友读信
  ↓                                      ↑
包装快递 ──────────────────────────> 拆开快递
  ↓                                      ↑
分拣中心 ──────────────────────────> 分拣中心
  ↓                                      ↑
运输车辆 ──────────────────────────> 运输车辆

每一层只关心自己的工作

  • 你只需要写信,不管怎么运输
  • 快递员只负责包装,不管写的什么
  • 司机只负责开车,不管包裹里是什么

这就是分层的思想

分层的好处

  1. 降低复杂度:每层只处理自己的任务
  2. 标准化接口:层与层之间有明确的接口
  3. 易于维护:修改某一层不影响其他层
  4. 可替换:可以更换某一层的实现

📊 OSI七层模型

OSI(Open Systems Interconnection)是国际标准化组织(ISO)制定的网络模型。

七层概览

┌─────────────┬────────────┬──────────────┬──────────────┐
│  层次       │  名称      │  作用        │  例子        │
├─────────────┼────────────┼──────────────┼──────────────┤
│  第7层      │  应用层    │  为用户提供  │  HTTP、FTP   │
│             │Application │  网络服务    │  SMTP、DNS   │
├─────────────┼────────────┼──────────────┼──────────────┤
│  第6层      │  表示层    │  数据格式转换│  加密、压缩  │
│             │Presentation│  编码、加密  │  JPEG、MPEG  │
├─────────────┼────────────┼──────────────┼──────────────┤
│  第5层      │  会话层    │  建立、管理  │  RPC、SQL    │
│             │Session     │  会话        │              │
├─────────────┼────────────┼──────────────┼──────────────┤
│  第4层      │  传输层    │  端到端通信  │  TCP、UDP    │
│             │Transport   │  可靠传输    │              │
├─────────────┼────────────┼──────────────┼──────────────┤
│  第3层      │  网络层    │  路由选择    │  IP、ICMP    │
│             │Network     │  寻址        │              │
├─────────────┼────────────┼──────────────┼──────────────┤
│  第2层      │  数据链路层│  帧传输      │  Ethernet    │
│             │Data Link   │  错误检测    │  WiFi、PPP   │
├─────────────┼────────────┼──────────────┼──────────────┤
│  第1层      │  物理层    │  比特传输    │  网线、光纤  │
│             │Physical    │  电信号      │  无线电波    │
└─────────────┴────────────┴──────────────┴──────────────┘

记忆口诀

从上到下

  • 应(应用层)
  • 表(表示层)
  • 会(会话层)
  • 传(传输层)
  • 网(网络层)
  • 数(数据链路层)
  • 物(物理层)

英文口诀:All People Seem To Need Data Processing

🔍 各层详解

第7层:应用层(Application Layer)

作用:为应用程序提供网络服务

通俗理解:你直接使用的软件层面

例子

  • 浏览器打开网页(HTTP/HTTPS)
  • 收发邮件(SMTP/POP3)
  • 下载文件(FTP)
  • 域名解析(DNS)

类比:快递公司的客服窗口


第6层:表示层(Presentation Layer)

作用:数据格式转换、加密、压缩

通俗理解:翻译官

例子

  • JPEG图片格式
  • MP3音频格式
  • 加密算法(SSL/TLS)
  • 字符编码(UTF-8)

类比:快递包装、封装


第5层:会话层(Session Layer)

作用:建立、管理、终止会话

通俗理解:负责通话的接线员

例子

  • 登录会话
  • 数据库连接
  • RPC远程调用

类比:快递单号管理系统


第4层:传输层(Transport Layer)

作用:端到端的可靠传输

通俗理解:确保包裹完整送达

例子

  • TCP:可靠传输,确保数据不丢失
  • UDP:快速传输,不保证可靠

关键概念:端口号(区分不同的应用)

类比:快递公司的分发系统


第3层:网络层(Network Layer)

作用:路由选择和寻址

通俗理解:找到最佳路径

例子

  • IP协议(IP地址)
  • 路由器工作在这一层

关键概念:IP地址(定位设备位置)

类比:快递运输路线规划


作用:帧传输,相邻节点之间的数据传输

通俗理解:同一条街道内的传送

例子

  • 以太网(Ethernet)
  • WiFi
  • MAC地址

关键概念:MAC地址(网卡的物理地址)

类比:同城快递站点之间的传递


第1层:物理层(Physical Layer)

作用:在物理媒介上传输比特流

通俗理解:实际的传输介质

例子

  • 网线(双绞线)
  • 光纤
  • 无线电波

关键概念:电信号、光信号、无线信号

类比:快递车、飞机、轮船

📦 数据封装过程

当你发送数据时,数据会经过封装过程:

应用层:    [用户数据]
              ↓ 添加应用层头部
表示层:    [表示层头部|用户数据]
              ↓ 添加会话层头部
会话层:    [会话层头部|表示层头部|用户数据]
              ↓ 添加传输层头部
传输层:    [TCP头部|数据] ← 称为"段"(Segment)
              ↓ 添加网络层头部
网络层:    [IP头部|TCP头部|数据] ← 称为"包"(Packet)
              ↓ 添加数据链路层头部和尾部
数据链路层:[帧头|IP头部|TCP头部|数据|帧尾] ← 称为"帧"(Frame)
              ↓ 转换为比特流
物理层:    01010101010101... ← 比特流(Bits)

类比理解

你写的信     →  应用层数据
装进信封     →  传输层添加端口信息
写上地址     →  网络层添加IP地址
放入包裹箱   →  数据链路层添加MAC地址
快递车运输   →  物理层传输

🔧 实战项目:协议分层演示

让我们编写一个程序,模拟OSI七层模型的数据封装过程!

代码实现

# day03_osi_demo.py
# 功能:演示OSI七层模型的数据封装和解封装过程

class OSILayer:
    """OSI模型的基础层类"""

    def __init__(self, name, layer_num):
        self.name = name
        self.layer_num = layer_num

    def encapsulate(self, data):
        """封装数据:添加本层头部"""
        header = f"[{self.name}头部]"
        return header + data

    def decapsulate(self, data):
        """解封装数据:移除本层头部"""
        header = f"[{self.name}头部]"
        if data.startswith(header):
            return data[len(header):]
        return data


class PhysicalLayer(OSILayer):
    """物理层:第1层"""

    def __init__(self):
        super().__init__("物理层", 1)

    def encapsulate(self, data):
        """将数据转换为比特流"""
        bits = ''.join(format(ord(c), '08b') for c in data)
        print(f"📡 {self.name}: 将数据转换为比特流")
        print(f"   比特流(前64位): {bits[:64]}...")
        return bits

    def decapsulate(self, bits):
        """将比特流转换为数据"""
        chars = []
        for i in range(0, len(bits), 8):
            byte = bits[i:i+8]
            if len(byte) == 8:
                chars.append(chr(int(byte, 2)))
        data = ''.join(chars)
        print(f"📡 {self.name}: 将比特流转换为数据")
        return data


class DataLinkLayer(OSILayer):
    """数据链路层:第2层"""

    def __init__(self):
        super().__init__("数据链路层", 2)

    def encapsulate(self, data):
        """添加MAC地址(帧头和帧尾)"""
        mac_src = "AA:BB:CC:DD:EE:FF"  # 源MAC地址
        mac_dst = "11:22:33:44:55:66"  # 目标MAC地址
        frame = f"[帧头|源MAC:{mac_src}|目标MAC:{mac_dst}]{data}[帧尾|CRC校验]"
        print(f"🔗 {self.name}: 添加MAC地址")
        print(f"   源MAC: {mac_src}")
        print(f"   目标MAC: {mac_dst}")
        return frame

    def decapsulate(self, frame):
        """移除MAC地址"""
        # 简化处理:移除帧头和帧尾
        start = frame.find("]") + 1
        end = frame.rfind("[")
        data = frame[start:end]
        print(f"🔗 {self.name}: 移除MAC地址")
        return data


class NetworkLayer(OSILayer):
    """网络层:第3层"""

    def __init__(self):
        super().__init__("网络层", 3)

    def encapsulate(self, data):
        """添加IP地址"""
        ip_src = "192.168.1.100"  # 源IP地址
        ip_dst = "93.184.216.34"  # 目标IP地址(example.com)
        packet = f"[IP头|源IP:{ip_src}|目标IP:{ip_dst}|TTL:64]{data}"
        print(f"🌐 {self.name}: 添加IP地址")
        print(f"   源IP: {ip_src}")
        print(f"   目标IP: {ip_dst}")
        return packet

    def decapsulate(self, packet):
        """移除IP头部"""
        start = packet.find("]") + 1
        print(f"🌐 {self.name}: 移除IP头部")
        return start and packet[start:] or packet


class TransportLayer(OSILayer):
    """传输层:第4层"""

    def __init__(self):
        super().__init__("传输层", 4)

    def encapsulate(self, data):
        """添加端口号(TCP头部)"""
        port_src = 54321  # 源端口
        port_dst = 80     # 目标端口(HTTP)
        segment = f"[TCP头|源端口:{port_src}|目标端口:{port_dst}|序号:12345]{data}"
        print(f"🚚 {self.name}: 添加端口号(TCP协议)")
        print(f"   源端口: {port_src}")
        print(f"   目标端口: {port_dst} (HTTP)")
        return segment

    def decapsulate(self, segment):
        """移除TCP头部"""
        start = segment.find("]") + 1
        print(f"🚚 {self.name}: 移除TCP头部")
        return segment[start:]


class SessionLayer(OSILayer):
    """会话层:第5层"""

    def __init__(self):
        super().__init__("会话层", 5)

    def encapsulate(self, data):
        """建立会话"""
        session_id = "SESSION-20250105-12345"
        session_data = f"[会话头|会话ID:{session_id}]{data}"
        print(f"💬 {self.name}: 建立会话")
        print(f"   会话ID: {session_id}")
        return session_data

    def decapsulate(self, data):
        """终止会话"""
        start = data.find("]") + 1
        print(f"💬 {self.name}: 解析会话信息")
        return data[start:]


class PresentationLayer(OSILayer):
    """表示层:第6层"""

    def __init__(self):
        super().__init__("表示层", 6)

    def encapsulate(self, data):
        """数据格式转换"""
        # 这里简化为添加编码信息
        formatted_data = f"[格式|编码:UTF-8|压缩:无|加密:无]{data}"
        print(f"🎨 {self.name}: 数据格式处理")
        print(f"   编码: UTF-8")
        return formatted_data

    def decapsulate(self, data):
        """数据格式还原"""
        start = data.find("]") + 1
        print(f"🎨 {self.name}: 数据格式还原")
        return data[start:]


class ApplicationLayer(OSILayer):
    """应用层:第7层"""

    def __init__(self):
        super().__init__("应用层", 7)

    def encapsulate(self, data):
        """生成HTTP请求"""
        http_request = f"GET / HTTP/1.1\\nHost: example.com\\n\\n{data}"
        print(f"📱 {self.name}: 生成HTTP请求")
        print(f"   请求: GET / HTTP/1.1")
        print(f"   主机: example.com")
        return http_request

    def decapsulate(self, data):
        """解析HTTP响应"""
        print(f"📱 {self.name}: 解析HTTP响应")
        return data


class OSIModel:
    """OSI七层模型"""

    def __init__(self):
        # 创建各层对象
        self.layers = [
            ApplicationLayer(),    # 第7层
            PresentationLayer(),   # 第6层
            SessionLayer(),        # 第5层
            TransportLayer(),      # 第4层
            NetworkLayer(),        # 第3层
            DataLinkLayer(),       # 第2层
            PhysicalLayer(),       # 第1层
        ]

    def send_data(self, data):
        """发送数据:从应用层到物理层"""
        print("=" * 70)
        print("📤 数据发送过程(封装)".center(70))
        print("=" * 70)
        print(f"\n原始数据: {data}\n")

        current_data = data

        # 从应用层到物理层,逐层封装
        for layer in self.layers:
            print(f"\n{'▼' * 35}")
            current_data = layer.encapsulate(current_data)
            if layer.layer_num > 1:  # 物理层的输出太长,不显示完整数据
                print(f"   数据长度: {len(current_data)} 字符")

        print("\n" + "=" * 70)
        return current_data

    def receive_data(self, data):
        """接收数据:从物理层到应用层"""
        print("\n" + "=" * 70)
        print("📥 数据接收过程(解封装)".center(70))
        print("=" * 70)

        current_data = data

        # 从物理层到应用层,逐层解封装
        for layer in reversed(self.layers):
            print(f"\n{'▲' * 35}")
            current_data = layer.decapsulate(current_data)

        print(f"\n最终数据: {current_data}")
        print("=" * 70)

        return current_data


def main():
    """主函数"""
    print("=" * 70)
    print("OSI七层模型数据封装演示".center(70))
    print("=" * 70)
    print("\n📚 本程序演示OSI七层模型的数据封装和解封装过程")
    print()

    # 创建OSI模型
    osi = OSIModel()

    # 要发送的数据
    original_data = "Hello, Network World!"

    print(f"🎯 准备发送数据: \"{original_data}\"")
    print()

    # 发送数据(封装过程)
    transmitted_data = osi.send_data(original_data)

    # 模拟数据传输
    print("\n" + "⚡" * 35)
    print("   数据通过网络传输中...")
    print("⚡" * 35)

    # 接收数据(解封装过程)
    received_data = osi.receive_data(transmitted_data)

    # 验证
    print("\n" + "=" * 70)
    print("✅ 传输完成!".center(70))
    print("=" * 70)
    print(f"\n发送的数据: {original_data}")
    print(f"接收的数据: {received_data}")

    if "Hello, Network World!" in received_data:
        print("\n🎉 数据传输成功!")
    else:
        print("\n❌ 数据传输失败!")


if __name__ == "__main__":
    main()

运行程序

cd code/day03
python day03_osi_demo.py

预期输出

程序会详细展示数据在OSI七层模型中的封装和解封装过程,帮助你直观理解每一层的作用。

🎓 知识小结

今天学到了什么?

  1. ✅ OSI七层模型是网络通信的标准模型
  2. ✅ 每一层都有明确的职责
  3. ✅ 数据发送时逐层封装,接收时逐层解封装
  4. ✅ 分层的优点是降低复杂度、便于维护

OSI七层速记

层次名称关键词协议示例
7应用层用户接口HTTP、FTP、DNS
6表示层格式转换SSL、JPEG
5会话层会话管理RPC、SQL
4传输层端到端TCP、UDP
3网络层路由寻址IP、ICMP
2数据链路层帧传输Ethernet、WiFi
1物理层比特流网线、光纤

重要概念

  • 封装(Encapsulation):发送数据时,逐层添加头部信息
  • 解封装(Decapsulation):接收数据时,逐层移除头部信息
  • PDU(Protocol Data Unit):协议数据单元
    • 应用层:消息(Message)
    • 传输层:段(Segment)
    • 网络层:包(Packet)
    • 数据链路层:帧(Frame)
    • 物理层:比特(Bit)

💪 练习题

练习1:层次识别

以下操作分别在哪一层完成?

  1. 输入网址 www.baidu.com
  2. 将域名解析为IP地址
  3. 添加源端口和目标端口
  4. 选择路由路径
  5. 将数据转换为电信号

练习2:绘制封装过程

画出"发送一封邮件"的完整封装过程,标注每一层添加的信息。

练习3:思考题

  1. 为什么要分成7层?能不能只分3层或分10层?
  2. 如果没有分层,会有什么问题?
  3. 哪些层是软件实现的?哪些是硬件实现的?

练习4:代码扩展

修改演示程序,添加以下功能:

  1. 显示每层数据的大小变化
  2. 模拟数据在传输过程中丢失的情况
  3. 添加错误检测和重传机制

📚 扩展阅读

OSI vs TCP/IP模型

OSI是理论模型,TCP/IP是实际使用的模型:

OSI七层模型              TCP/IP四层模型
┌─────────────┐
│  应用层     │ \        ┌─────────────┐
├─────────────┤  \       │  应用层     │
│  表示层     │   } ───> │             │
├─────────────┤  /       │             │
│  会话层     │ /        └─────────────┘
├─────────────┤          ┌─────────────┐
│  传输层     │  ─────>  │  传输层     │
├─────────────┤          └─────────────┘
│  网络层     │  ─────>  ┌─────────────┐
├─────────────┤          │  网络层     │
│ 数据链路层  │ \        └─────────────┘
├─────────────┤  } ───>  ┌─────────────┐
│  物理层     │ /        │ 网络接口层  │
└─────────────┘          └─────────────┘

明天我们将详细学习TCP/IP模型!

🎯 明天预告

第4天:TCP/IP四层模型

我们将学习:

  • TCP/IP模型和OSI模型的区别
  • TCP/IP各层的详细功能
  • 实际网络中如何使用TCP/IP
  • 编写程序分析真实的网络数据包

💡 今日金句:分层不是为了复杂化,而是为了简单化!

👉 上一天:网络的分类和拓扑结构 | 返回目录 | 下一天:TCP/IP四层模型