TCP协议
TCP协议详解 - 从基础到安全
概述
TCP (Transmission Control Protocol) 是传输层的面向连接、可靠的字节流传输协议。本文将深入解析TCP的核心机制、设计原理和安全考虑。
1. TCP三次握手详解
1.1 三次握手流程
客户端 服务器
| |
|-------- SYN ---------->| (1) 请求连接 (SYN=1, seq=x)
|<--- SYN + ACK ---------| (2) 确认连接 (SYN=1, ACK=1, seq=y, ack=x+1)
|-------- ACK ---------->| (3) 握手完成 (ACK=1, seq=x+1, ack=y+1)
| |
| 连接建立完成 |
详细步骤:
-
第一次握手 (SYN)
- 客户端发送SYN包,SYN=1,seq=x(随机初始序列号)
- 客户端进入SYN_SENT状态
- 表示:"我想和你建立连接"
-
第二次握手 (SYN+ACK)
- 服务器收到SYN,回复SYN+ACK包
- SYN=1, ACK=1, seq=y(服务器的初始序列号), ack=x+1
- 服务器进入SYN_RCVD状态
- 表示:"我收到了你的请求,同意建立连接,这是我的序列号"
-
第三次握手 (ACK)
- 客户端发送ACK包,ACK=1, seq=x+1, ack=y+1
- 客户端和服务器都进入ESTABLISHED状态
- 表示:"我收到了你的确认,连接建立完成"
1.2 为什么不能是两次握手?
核心问题:防止历史连接请求
假设场景:两次握手的问题
客户端 服务器
| |
|--- 过期的SYN(seq=100) ->| (1) 网络延迟,过期请求
|--- 新的SYN(seq=200) --->| (2) 正常的新请求
|<-- SYN+ACK(ack=101) ---| (3) 服务器响应过期请求
|<-- SYN+ACK(ack=201) ---| (4) 服务器响应新请求
两次握手的问题:
- 无法区分新旧连接:服务器无法判断收到的SYN是否为历史请求
- 资源浪费:服务器会为过期请求分配资源
- 序列号混乱:无法确保双方序列号同步
三次握手解决方案:
- 第三次握手让客户端确认服务器的响应
- 客户端可以丢弃过期连接的响应
- 只有完整的三次握手才建立连接
1.3 三次握手后可以携带数据吗?
答案:可以,但有条件
正常三次握手 + 数据传输:
客户端 服务器
| |
|-------- SYN ---------->| (1) SYN, seq=100
|<--- SYN + ACK ---------| (2) SYN+ACK, seq=200, ack=101
|-- ACK + DATA --------->| (3) ACK + 应用数据, seq=101, ack=201
可以携带数据的情况:
- 第三次握手包可以携带数据
- 连接已建立,开始数据传输阶段
- 需要正确设置序列号和确认号
不建议在前两次握手携带数据的原因:
- SYN包携带数据会增加SYN Flood攻击风险
- 连接未完全建立时数据可能丢失
- 协议设计原则:握手和数据传输分离
2. TCP四次挥手详解
2.1 四次挥手流程
客户端 服务器
| |
|------- FIN ----------->| (1) 客户端关闭 (FIN=1, seq=u)
|<------ ACK ------------| (2) 服务器确认 (ACK=1, ack=u+1)
| |
|<------ FIN ------------| (3) 服务器关闭 (FIN=1, seq=v)
|------- ACK ----------->| (4) 客户端确认 (ACK=1, ack=v+1)
| |
| 连接完全关闭 |
详细步骤:
-
第一次挥手 (FIN)
- 客户端发送FIN包,表示不再发送数据
- 客户端进入FIN_WAIT_1状态
-
第二次挥手 (ACK)
- 服务器确认收到FIN包
- 服务器进入CLOSE_WAIT状态
- 客户端进入FIN_WAIT_2状态
-
第三次挥手 (FIN)
- 服务器发送FIN包,表示准备关闭连接
- 服务器进入LAST_ACK状态
-
第四次挥手 (ACK)
- 客户端确认服务器的FIN包
- 客户端进入TIME_WAIT状态
- 服务器收到ACK后直接关闭连接
2.2 为什么不能是三次挥手?
核心原因:TCP是全双工通信
全双工连接示意:
客户端 ←→ 服务器
发送通道 ←--------- 需要单独关闭
接收通道 --------→ 需要单独关闭
四次挥手的必要性:
- 双向独立关闭:每个方向的数据流需要独立关闭
- 数据完整性:确保所有数据传输完成再关闭
- 优雅关闭:给应用层时间处理剩余数据
特殊情况:三次挥手
优化的三次挥手(服务器立即关闭):
客户端 服务器
| |
|------- FIN ----------->| (1) 客户端关闭
|<--- FIN + ACK ---------| (2) 服务器同时确认和关闭
|------- ACK ----------->| (3) 客户端最终确认
3. TIME_WAIT 和 CLOSE_WAIT 详解
3.1 TIME_WAIT 状态
定义和持续时间:
- 主动关闭方在发送最后一个ACK后进入的状态
- 持续时间:2MSL (Maximum Segment Lifetime,通常为2-4分钟)
- 状态位置:在四次挥手的最后阶段
TIME_WAIT状态流程:
客户端(主动关闭) 服务器
| |
|<------ FIN ------------| 服务器FIN
|------- ACK ----------->| 客户端ACK (进入TIME_WAIT)
| |
| 等待 2MSL 时间 |
| |
| 连接彻底关闭 |
TIME_WAIT的作用:
- 确保最后的ACK到达:如果ACK丢失,服务器会重发FIN
- 避免新连接收到旧数据:确保网络中的旧数据包完全消失
- 防止端口重用问题:避免新连接与旧连接混淆
TIME_WAIT过多的问题:
# 查看TIME_WAIT连接数
netstat -an | grep TIME_WAIT | wc -l
# 常见问题:
# 1. 端口耗尽
# 2. 内存占用
# 3. 连接建立延迟
3.2 CLOSE_WAIT 状态
定义和特点:
- 被动关闭方收到FIN后,发送ACK进入的状态
- 等待应用层调用close()关闭连接
- 如果应用层不关闭,会一直保持此状态
CLOSE_WAIT状态流程:
客户端 服务器(被动关闭)
| |
|------- FIN ----------->| 客户端FIN
|<------ ACK ------------| 服务器ACK (进入CLOSE_WAIT)
| |
| 服务器应用层处理 |
| |
|<------ FIN ------------| 服务器调用close()
|------- ACK ----------->| 客户端最终ACK
CLOSE_WAIT过多的问题:
- 应用层BUG:忘记调用close()
- 资源泄露:文件描述符耗尽
- 连接堆积:大量僵尸连接
# Python示例:正确处理连接关闭
try:
# 网络操作
response = socket.recv(1024)
# 处理数据
except Exception as e:
print(f"Error: {e}")
finally:
socket.close() # 确保连接关闭
3.3 状态对比总结
| 状态 | 角色 | 触发条件 | 持续时间 | 主要作用 | 常见问题 |
|---|---|---|---|---|---|
| TIME_WAIT | 主动关闭方 | 发送最后ACK后 | 2MSL | 确保可靠关闭 | 端口耗尽 |
| CLOSE_WAIT | 被动关闭方 | 收到FIN后 | 直到应用close() | 等待应用关闭 | 应用层忘记关闭 |
4. TCP头部结构详解
4.1 TCP头部格式
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Port | Destination Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Acknowledgment Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data | |U|A|P|R|S|F| |
| Offset| Reserved |R|C|S|S|Y|I| Window |
| | |G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Checksum | Urgent Pointer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4.2 各字段详解
基本字段 (20字节固定部分):
-
Source Port (16位)
- 源端口号
- 标识发送进程
-
Destination Port (16位)
- 目标端口号
- 标识接收进程
-
Sequence Number (32位)
- 序列号
- 数据包中第一个字节的序列号
- 用于数据排序和去重
-
Acknowledgment Number (32位)
- 确认号
- 期望收到的下一个字节的序列号
- 只有ACK=1时有效
-
Data Offset (4位)
- 数据偏移量
- TCP头部长度(以4字节为单位)
- 范围:5-15(20-60字节)
-
Reserved (6位)
- 保留字段,必须为0
-
Control Flags (6位)
URG: 紧急指针有效 ACK: 确认号有效 PSH: 推送标志(立即传递给应用层) RST: 重置连接 SYN: 同步序列号(建立连接) FIN: 结束连接 -
Window (16位)
- 接收窗口大小
- 流量控制机制
- 告知对方可接收的数据量
-
Checksum (16位)
- 校验和
- 覆盖头部和数据
- 用于错误检测
-
Urgent Pointer (16位)
- 紧急指针
- 指向紧急数据的最后一个字节
4.3 TCP选项字段
常见选项:
-
MSS (Maximum Segment Size)
Kind=2, Length=4, MSS Value (2 bytes) 用途:协商最大段大小 -
Window Scale
Kind=3, Length=3, Shift Count (1 byte) 用途:扩展窗口大小(最大1GB) -
SACK (Selective Acknowledgment)
Kind=4, Length=2 (SACK Permitted) Kind=5, Length=Variable (SACK Block) 用途:选择性确认,提高重传效率 -
Timestamp
Kind=8, Length=10, Timestamp Value, Timestamp Echo 用途:RTT测量和PAWS(防序列号回绕)
5. TCP拥塞控制详解
5.1 拥塞控制概述
目标:
- 防止网络拥塞
- 公平分配网络资源
- 最大化网络利用率
核心机制:
发送速率 = min(拥塞窗口, 接收窗口) / RTT
5.2 拥塞控制算法
5.2.1 慢启动 (Slow Start)
拥塞窗口变化:
cwnd = 1 MSS # 初始值
每收到一个ACK: cwnd += 1 # 指数增长
特点:
- 指数增长:1 → 2 → 4 → 8 → 16 ...
- 快速探测可用带宽
- 达到慢启动阈值(ssthresh)后进入拥塞避免
# 慢启动示例
def slow_start():
cwnd = 1 # 初始拥塞窗口
ssthresh = 16 # 慢启动阈值
while cwnd < ssthresh:
print(f"发送 {cwnd} 个段")
# 假设收到 cwnd 个ACK
cwnd *= 2 # 每个RTT翻倍
print("进入拥塞避免阶段")
5.2.2 拥塞避免 (Congestion Avoidance)
拥塞窗口变化:
每收到一个ACK: cwnd += 1/cwnd # 线性增长
每个RTT: cwnd += 1
特点:
- 线性增长,谨慎探测
- AIMD算法:Additive Increase, Multiplicative Decrease
5.2.3 快速重传 (Fast Retransmit)
触发条件:收到3个重复ACK
动作:立即重传丢失的数据包
快速重传示例:
发送方 接收方
| |
|------ Seg1 ------------>| 收到,ACK1
|------ Seg2 -----------X | 丢失
|------ Seg3 ------------>| 期望Seg2,发送ACK1
|------ Seg4 ------------>| 期望Seg2,发送ACK1
|------ Seg5 ------------>| 期望Seg2,发送ACK1
|<----- ACK1 x3 ----------| 收到3个重复ACK
|------ Seg2 ------------>| 快速重传
5.2.4 快速恢复 (Fast Recovery)
进入条件:检测到丢包(3个重复ACK)
动作:
1. ssthresh = cwnd / 2 # 阈值减半
2. cwnd = ssthresh + 3 # 拥塞窗口设为阈值+3
3. 每收到重复ACK: cwnd++ # 继续增长
4. 收到新ACK: cwnd = ssthresh # 恢复正常
5.3 现代拥塞控制算法
5.3.1 BBR (Bottleneck Bandwidth and RTT)
核心思想:
- 不依赖丢包检测拥塞
- 基于带宽和RTT测量
- 四个状态:Startup, Drain, ProbeBW, ProbeRTT
BBR算法:
发送速率 = 测量带宽 × RTT / 数据量
5.3.2 CUBIC
特点:
- 三次函数增长
- 对高带宽长延迟网络友好
- Linux默认算法
CUBIC窗口增长:
W(t) = C(t - K)³ + Wmax
其中:K = ∛(Wmax × β / C)
5.4 拥塞控制状态机
状态转换图:
[慢启动] --达到ssthresh--> [拥塞避免]
| |
| |
超时--> [慢启动] <--超时-- |
| | |
| | |
3重复ACK--> [快速恢复] <--3重复ACK--
6. TCP vs UDP 详细对比
6.1 核心差异对比
| 特性 | TCP | UDP |
|---|---|---|
| 连接性 | 面向连接 | 无连接 |
| 可靠性 | 可靠传输 | 不可靠传输 |
| 有序性 | 保证有序 | 不保证有序 |
| 流量控制 | 有 | 无 |
| 拥塞控制 | 有 | 无 |
| 头部开销 | 20-60字节 | 8字节 |
| 速度 | 相对较慢 | 快速 |
| 适用场景 | 可靠性要求高 | 实时性要求高 |
6.2 技术细节对比
6.2.1 连接管理
TCP连接管理:
建立连接:三次握手
数据传输:可靠的字节流
关闭连接:四次挥手
状态管理:11种连接状态
UDP连接管理:
无连接:直接发送数据
数据传输:尽力而为的数据报
无状态:发送即忘记
6.2.2 可靠性机制
TCP可靠性保证:
# TCP可靠性机制
class TCPReliability:
def __init__(self):
self.sequence_number = 0
self.ack_number = 0
self.send_buffer = {}
self.recv_buffer = {}
def send_data(self, data):
# 1. 分段
segments = self.segment_data(data)
# 2. 添加序列号
for segment in segments:
segment.seq = self.sequence_number
self.sequence_number += len(segment.data)
# 3. 发送并启动定时器
for segment in segments:
self.send_segment(segment)
self.start_timer(segment)
def handle_ack(self, ack):
# 4. 确认接收,取消定时器
if ack.ack_num in self.send_buffer:
self.stop_timer(ack.ack_num)
del self.send_buffer[ack.ack_num]
def handle_timeout(self, seq):
# 5. 超时重传
if seq in self.send_buffer:
self.retransmit(self.send_buffer[seq])
UDP无可靠性保证:
# UDP简单发送
class UDPSimple:
def send_data(self, data, address):
# 直接发送,不管结果
self.socket.sendto(data, address)
# 没有确认,没有重传,没有状态维护
6.2.3 性能特征
TCP性能开销:
连接建立:3次握手 (1.5 RTT)
数据传输:确认 + 重传 + 流控 + 拥塞控制
连接关闭:4次挥手 (2 RTT)
内存占用:连接状态 + 发送/接收缓冲区
UDP性能优势:
无连接开销:立即发送数据
无确认开销:单向传输
无状态开销:最小内存占用
无拥塞控制:最大发送速率
6.3 应用场景选择
6.3.1 TCP适用场景
1. Web应用 (HTTP/HTTPS)
- 要求数据完整性
- 可以容忍延迟
2. 文件传输 (FTP, SFTP)
- 数据不能丢失
- 顺序很重要
3. 邮件传输 (SMTP, IMAP)
- 可靠性至关重要
4. 远程登录 (SSH, Telnet)
- 命令不能丢失
5. 数据库连接
- 事务完整性
6.3.2 UDP适用场景
1. 视频直播/会议
- 实时性重要
- 丢失部分数据可接受
2. 在线游戏
- 低延迟需求
- 位置更新频繁
3. DNS查询
- 简单请求-响应
- 可以重试
4. DHCP
- 广播性质
- 简单配置
5. 音频流
- 实时传输
- 缓冲处理
7. TCP网络攻击与安全隐患
7.1 TCP协议层攻击
7.1.1 SYN Flood 攻击
攻击原理:
攻击者 目标服务器
| |
|------ SYN(伪造IP) ---->| 大量SYN请求
|------ SYN(伪造IP) ---->| 服务器分配资源
|------ SYN(伪造IP) ---->| 等待ACK(永远不来)
| |
| 服务器资源耗尽 |
攻击效果:
- 服务器半连接队列满
- 无法处理正常连接请求
- 拒绝服务攻击(DoS)
防护措施:
# SYN Flood防护
class SYNFloodProtection:
def __init__(self):
self.syn_cookies = True # 启用SYN Cookies
self.syn_backlog = 1024 # 调整半连接队列大小
self.syn_retries = 3 # 限制SYN重试次数
def handle_syn(self, syn_packet):
if self.is_syn_flood():
# 使用SYN Cookies而非分配连接状态
cookie = self.generate_syn_cookie(syn_packet)
return self.send_syn_ack_with_cookie(cookie)
else:
# 正常处理
return self.normal_syn_handling(syn_packet)
7.1.2 TCP RST 攻击
攻击原理:
攻击者监听网络流量,伪造RST包强制断开连接
正常通信:
客户端 <--------数据流-------> 服务器
↑ ↑
| |
|------ RST (伪造) --------->|
| |
连接被强制断开
攻击条件:
- 知道四元组(源IP、源端口、目标IP、目标端口)
- 序列号在接收窗口内
- 网络可达
防护措施:
- 使用IPSec/TLS加密
- 序列号随机化
- 网络访问控制
7.1.3 TCP Hijacking (会话劫持)
攻击流程:
1. 攻击者嗅探网络流量
2. 获取TCP连接状态信息
3. 预测序列号
4. 注入恶意数据包
5. 控制TCP会话
# TCP劫持示例(仅用于说明)
class TCPHijackingDemo:
def sniff_connection(self, target_ip, target_port):
# 1. 监听目标连接
packets = self.capture_packets(target_ip, target_port)
# 2. 分析序列号模式
seq_pattern = self.analyze_sequence_numbers(packets)
# 3. 预测下一个序列号
next_seq = self.predict_next_sequence(seq_pattern)
# 4. 构造恶意数据包
malicious_packet = self.craft_packet(
seq=next_seq,
data="malicious_payload"
)
# 5. 注入攻击数据
self.inject_packet(malicious_packet)
防护措施:
- 序列号强随机化
- TLS/SSL加密
- 网络分段
- 入侵检测系统
7.2 应用层攻击
7.2.1 HTTP Slowloris 攻击
攻击原理:
# Slowloris攻击模拟
class SlowlorisAttack:
def __init__(self, target_host, target_port):
self.target = (target_host, target_port)
self.sockets = []
def start_attack(self):
# 建立大量TCP连接
for i in range(1000):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(self.target)
# 发送不完整的HTTP请求
sock.send(b"GET / HTTP/1.1\r\n")
sock.send(b"Host: target.com\r\n")
# 故意不发送\r\n\r\n结束标志
self.sockets.append(sock)
# 定期发送额外的头部,保持连接
while True:
for sock in self.sockets:
try:
sock.send(b"X-Custom-Header: value\r\n")
time.sleep(10)
except:
# 连接断开,重新建立
self.sockets.remove(sock)
self.establish_new_connection()
7.2.2 慢速POST攻击
攻击原理:
1. 发送POST请求头,声明大量数据
2. 极其缓慢地发送POST数据
3. 占用服务器连接资源
4. 导致正常用户无法访问
7.3 网络层相关攻击
7.3.1 IP欺骗攻击
攻击场景:
真实客户端 IP: 192.168.1.100
攻击者伪造源IP发送TCP包
伪造的TCP包:
源IP: 192.168.1.100 (伪造)
目标IP: 192.168.1.1
源端口: 随机
目标端口: 80
防护措施:
# IP欺骗防护
class AntiSpoofing:
def __init__(self):
self.trusted_networks = ['192.168.1.0/24']
def validate_source_ip(self, packet):
source_ip = packet.src_ip
# 1. 检查源IP是否在合理范围
if self.is_bogon_ip(source_ip):
return False
# 2. 反向路径验证
if not self.reverse_path_forwarding_check(source_ip):
return False
# 3. 地理位置验证
if not self.geo_location_check(source_ip):
return False
return True
7.4 综合防护策略
7.4.1 多层防护体系
防护层次:
┌─────────────────────────────────────┐
│ 应用层防护 (WAF, 输入验证) │
├─────────────────────────────────────┤
│ 传输层防护 (SYN Cookies, 限流) │
├─────────────────────────────────────┤
│ 网络层防护 (反欺骗, ACL) │
├─────────────────────────────────────┤
│ 物理层防护 (网络隔离) │
└─────────────────────────────────────┘
7.4.2 监控和检测
# TCP攻击检测系统
class TCPAttackDetector:
def __init__(self):
self.syn_rate_threshold = 1000 # SYN包速率阈值
self.connection_threshold = 5000 # 连接数阈值
def detect_syn_flood(self, metrics):
syn_rate = metrics['syn_packets_per_second']
if syn_rate > self.syn_rate_threshold:
return {
'attack_type': 'SYN_FLOOD',
'severity': 'HIGH',
'source_ips': metrics['top_source_ips']
}
def detect_connection_exhaustion(self, metrics):
active_connections = metrics['active_tcp_connections']
if active_connections > self.connection_threshold:
return {
'attack_type': 'CONNECTION_EXHAUSTION',
'severity': 'MEDIUM',
'connection_count': active_connections
}
def monitor_tcp_anomalies(self):
while True:
metrics = self.collect_tcp_metrics()
# 检测各种攻击
attacks = []
attacks.extend(self.detect_syn_flood(metrics))
attacks.extend(self.detect_connection_exhaustion(metrics))
attacks.extend(self.detect_tcp_hijacking(metrics))
# 触发告警和防护措施
for attack in attacks:
self.trigger_alert(attack)
self.activate_countermeasures(attack)
time.sleep(1)
8. TCP性能调优
8.1 操作系统级优化
# Linux TCP参数调优
# /etc/sysctl.conf
# TCP缓冲区调优
net.core.rmem_max = 134217728 # 最大接收缓冲区
net.core.wmem_max = 134217728 # 最大发送缓冲区
net.ipv4.tcp_rmem = 4096 87380 134217728 # TCP接收缓冲区
net.ipv4.tcp_wmem = 4096 65536 134217728 # TCP发送缓冲区
# 连接队列调优
net.core.somaxconn = 1024 # 监听队列最大长度
net.ipv4.tcp_max_syn_backlog = 2048 # SYN队列长度
# TIME_WAIT调优
net.ipv4.tcp_tw_reuse = 1 # 重用TIME_WAIT连接
net.ipv4.tcp_fin_timeout = 30 # FIN_WAIT_2超时时间
# 拥塞控制
net.ipv4.tcp_congestion_control = bbr # 使用BBR算法
8.2 应用层优化
# 应用层TCP优化
class TCPOptimization:
def __init__(self):
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def optimize_socket(self):
# 1. 设置缓冲区大小
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 262144)
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 262144)
# 2. 启用TCP_NODELAY(禁用Nagle算法)
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
# 3. 设置Keep-Alive
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
# 4. 设置超时
self.socket.settimeout(30)
def efficient_send(self, data):
# 批量发送减少系统调用
chunk_size = 8192
offset = 0
while offset < len(data):
chunk = data[offset:offset + chunk_size]
sent = self.socket.send(chunk)
offset += sent
总结
TCP作为互联网的核心协议,其设计体现了网络通信的复杂性和可靠性要求:
- 三次握手和四次挥手确保连接的可靠建立和优雅关闭
- 复杂的状态管理(如TIME_WAIT、CLOSE_WAIT)保证网络的稳定性
- 精心设计的头部结构支持各种高级功能
- 拥塞控制机制保证网络的公平性和效率
- 与UDP的差异体现了可靠性与性能的权衡
- 安全隐患和防护需要多层次的安全策略
理解TCP的这些机制对于网络编程、系统优化和安全防护都至关重要。在实际应用中,需要根据具体场景选择合适的协议和优化策略。
本文来自博客园,作者:MadLongTom,转载请注明原文链接:https://www.cnblogs.com/madtom/p/19044622
浙公网安备 33010602011771号