计算机网络高频考点深度解析:传输层、网络层与应用层核心算法

考研408计算机网络高频考点深度解析:传输层、网络层与应用层核心算法

作者:Crown_22 | 计算机科学 | 技术分享


前言

408计算机网络是考研四门专业课中知识点最琐碎、协议最多样的一门。很多同学觉得"背就行了",但近年来命题趋势明显偏向理解应用——给你一个场景,让你分析数据包的流向、计算序列号、判断是否丢包重传。

本文聚焦408计网中最高频、最易错的核心算法和协议机制,每个考点都用代码模拟+图解+真题改编的方式深度解析。


在这里插入图片描述

一、TCP 三次握手与四次挥手(必考)

1.1 三次握手的状态机

这是408必考题,几乎每年都有相关选择题。关键不是背流程,而是理解为什么要三次

# TCP 三次握手模拟器
class TCPConnection:
    """TCP 连接状态模拟"""
    
    # 状态定义
    CLOSED = "CLOSED"
    LISTEN = "LISTEN"
    SYN_SENT = "SYN_SENT"
    SYN_RCVD = "SYN_RCVD"
    ESTABLISHED = "ESTABLISHED"
    
    def __init__(self, name: str):
        self.name = name
        self.state = self.CLOSED
        self.seq = 0          # 发送序列号
        self.ack = 0          # 确认序列号
        self.peer_seq = 0     # 对方的序列号
    
    def send_syn(self) -> dict:
        """第一次握手:客户端发送 SYN"""
        assert self.state == self.CLOSED, f"{
     
     self.name}: 状态错误 {
     
     self.state}"
        self.seq = 100  # 初始序列号(实际是随机的)
        self.state = self.SYN_SENT
        print(f"[{
     
     self.name}] → SYN, seq={
     
     self.seq}")
        return {
   
   "type": "SYN", "seq": self.seq}
    
    def recv_syn_send_ack(self, packet: dict) -> dict:
        """第二次握手:服务端收到 SYN,发送 SYN+ACK"""
        assert self.state == self.LISTEN, f"{
     
     self.name}: 状态错误 {
     
     self.state}"
        self.peer_seq = packet["seq"]
        self.seq = 200  # 服务端初始序列号
        self.ack = self.peer_seq + 1
        self.state = self.SYN_RCVD
        print(f"[{
     
     self.name}] ← SYN, seq={
     
     self.peer_seq}")
        print(f"[{
     
     self.name}] → SYN+ACK, seq={
     
     self.seq}, ack={
     
     self.ack}")
        return {
   
   "type": "SYN+ACK", "seq": self.seq, "ack": self.ack}
    
    def recv_ack(self, packet: dict):
        """第三次握手:客户端收到 ACK"""
        assert self.state == self.SYN_SENT, f"{
     
     self.name}: 状态错误 {
     
     self.state}"
        self.ack = packet["seq"] + 1
        self.state = self.ESTABLISHED
        print(f"[{
     
     self.name}] ← SYN+ACK, seq={
     
     packet['seq']}, ack={
     
     packet['ack']}")
        print(f"[{
     
     self.name}] → ACK, ack={
     
     self.ack}")
        print(f"[{
     
     self.name}] 连接建立!状态 → ESTABLISHED")
    
    def recv_syn_ack_establish(self, packet: dict):
        """服务端收到第三次 ACK"""
        assert self.state == self.SYN_RCVD, f"{
     
     self.name}: 状态错误 {
     
     self.state}"
        self.state = self.ESTABLISHED
        print(f"[{
     
     self.name}] ← ACK, ack={
     
     packet['ack']}")
        print(f"[{
     
     self.name}] 连接建立!状态 → ESTABLISHED")


def simulate_three_way_handshake():
    """模拟三次握手完整过程"""
    print("=" * 50)
    print("TCP 三次握手模拟")
    print("=" * 50)
    
    client = TCPConnection("客户端")
    server = TCPConnection("服务端")
    server.state = TCPConnection.LISTEN
    
    # 第一次握手
    syn_packet = client.send_syn()
    
    # 第二次握手
    syn_ack_packet = server.recv_syn_send_ack(syn_packet)
    
    # 第三次握手
    client.recv_ack(syn_ack_packet)
    server.recv_syn_ack_establish({
   
   "ack": client.ack})
    
    print(f"\n最终状态: 客户端={
     
     client.state}, 服务端={
     
     server.state}")

simulate_three_way_handshake()

输出

==================================================
TCP 三次握手模拟
==================================================
[客户端] → SYN, seq=100
[服务端] ← SYN, seq=100
[服务端] → SYN+ACK, seq=200, ack=101
[客户端] ← SYN+ACK, seq=200, ack=101
[客户端] → ACK, ack=201
[客户端] 连接建立!状态 → ESTABLISHED
[服务端] ← ACK, ack=201
[服务端] 连接建立!状态 → ESTABLISHED

最终状态: 客户端=ESTABLISHED, 服务端=ESTABLISHED

1.2 为什么不能两次握手?

# 模拟两次握手的问题:历史重复连接
def simulate_two_way_problem():
    """两次握手的经典问题:旧的 SYN 包导致错误连接"""
    print("=" * 50)
    print("两次握手的问题演示")
    print("=" * 50)
    
    # 场景:客户端发送了 SYN,但网络延迟,SYN 迟到了
    print("场景:客户端的旧 SYN 包延迟到达服务端")
    print()
    
    # 客户端旧连接的 SYN(序列号=100)
    old_syn = {
   
   "type": "SYN", "seq": 100, "note": "这是旧连接的SYN,已过期"}
    print(f"[旧SYN] seq=100, 已过期但延迟到达")
    
    # 服务端收到旧 SYN,误以为是新连接
    print(f"[服务端] 收到旧SYN,以为是新连接")
    print(f"[服务端] 发送 SYN+ACK, seq=200, ack=101")
    print(f"[服务端] 状态 → ESTABLISHED(服务端单方面认为连接建立)")
    print()
    
    # 问题:客户端根本不知道这个连接
    print("[问题] 客户端没有发起这个连接,不会发送数据")
    print("[问题] 服务端一直等待,浪费资源(半开连接)")
    print()
    print("[解决] 三次握手时,客户端收到 SYN+ACK 后会检查:")
    print("  - 如果 ack 号不对(不是自己发的 SYN 的响应),会发送 RST")
    print("  - 只有 ack 号正确才会发送第三次 ACK")

simulate_two_way_problem()

1.3 四次挥手与 TIME_WAIT

# TCP 四次挥手模拟
class TCPDisconnect:
    """TCP 四次挥手模拟"""
    
    FIN_WAIT_1 = "FIN_WAIT_1"
    FIN_WAIT_2 = "FIN_WAIT_2"
    TIME_WAIT = "TIME_WAIT"
    CLOSE_WAIT = "CLOSE_WAIT"
    LAST_ACK = "LAST_ACK"
    CLOSED = "CLOSED"
    ESTABLISHED = "ESTABLISHED"
    
    def __init__(self, name: str):
        self.name = name
        self.state = self.ESTABLISHED
    
    def send_fin(self) -> dict:
        """发送 FIN"""
        self.state = self.FIN_WAIT_1
        print(f"[{
     
     self.name}] → FIN, 状态 → FIN_WAIT_1")
        return {
   
   "type": "FIN"}
    
    def recv_fin_send_ack(self, packet: dict) -> dict:
        """收到 FIN,发送 ACK"""
        self.state = self.CLOSE_WAIT
        print(f"[{
     
     self.name}] ← FIN")
        print(f"[{
     
     self.name}] → ACK, 状态 → CLOSE_WAIT")
        return {
   
   "type": "ACK"}
    
    def send_fin_close(self) -> dict:
        """CLOSE_WAIT 状态下发送自己的 FIN"""
        self.state = self.LAST_ACK
        print(f"[{
     
     self.name}] → FIN, 状态 → LAST_ACK")
        return {
   
   "type": "FIN"}
    
    def recv_ack_fin_wait(self, packet: dict):
        """FIN_WAIT_1 收到 ACK"""
        self.state = self.FIN_WAIT_2
        print(f"[{
     
     self.name}] ← ACK, 状态 → FIN_WAIT_2")
    
    def recv_fin_send_final_ack(self, packet: dict):
        """FIN_WAIT_2 收到 FIN,发送最后的 ACK"""
        self.state = self.TIME_WAIT
        print(f"[{
     
     self.name}] ← FIN")
        print(f"[{
     
     self.name}] → ACK, 状态 → TIME_WAIT")
        print(f"[{
     
     self.name}] 等待 2MSL (60秒) 后关闭")
    
    def recv_final_ack(self, packet: dict):
        """LAST_ACK 收到最终 ACK"""
        self.state = self.CLOSED
        print(f"[{
     
     self.name}] ← ACK, 状态 → CLOSED")


def simulate_four_way_handshake():
    """模拟四次挥手"""
    print("=" * 50)
    print("TCP 四次挥手模拟")
    print("=" * 50)
    
    client = TCPDisconnect("客户端")
    server = TCPDisconnect("服务端")
    
    # 第一次挥手:客户端发 FIN
    fin1 = client.send_fin()
    
    # 第二次挥手:服务端回 ACK
    ack1 = server.recv_fin_send_ack(fin1)
    
    # 服务端可能还有数据要发,等一会儿...
    print(f"[服务端] 继续发送剩余数据..."
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值