考研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"[服务端] 继续发送剩余数据..."



被折叠的 条评论
为什么被折叠?



