目录
TCP协议简介
TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。它具有以下特点:
• 面向连接:通信前需要建立连接(三次握手),通信结束后需要断开连接(四次挥手) • 可靠传输:使用确认机制和重传机制确保数据不丢失 • 流量控制:通过滑动窗口机制控制发送速率 • 拥塞控制:避免网络拥塞,动态调整传输速率
📦 三次握手过程——例子:快递员确认收货地址
假设你的浏览器(Chrome)是寄件人,服务器(Apache)是收件人,TCP协议(运输层)是快递公司,三次握手就像快递员上门确认地址的过程:
1. 第一次握手(浏览器→服务器)
• 动作:
• 浏览器发送一个SYN=1
的包裹(SYN是同步序列号请求),并生成随机序号seq=1000
• 快递员(TCP)说:“您好,我是快递员,Chrome想给Apache寄包裹,您能收吗?”
• 状态变化:
• 客户端状态:CLOSED → SYN_SENT
• 服务端状态:LISTEN
2. 第二次握手(服务器→浏览器)
• 动作:
• 服务器收到SYN
后,回复SYN=1 + ACK=1
,序号seq=2000
,确认号ack=1001
• 快递员反馈:“Apache确认能收件,请把包裹按编号1001开始发给我!”
• 状态变化:
• 服务端状态:LISTEN → SYN_RECEIVED
• 技术点:
• ACK=1
表示确认收到第一次握手
• ack=1001
表示"我期待收到下一个编号是1001的数据"
• 确认号计算规则:收到的序号+1
3. 第三次握手(浏览器→服务器)
• 动作:
• 浏览器发送ACK=1
,序号seq=1001
,确认号ack=2001
• 快递员说:“好的,我会按您的要求开始寄送!”
• 状态变化:
• 客户端状态:SYN_SENT → ESTABLISHED
• 服务端状态:SYN_RECEIVED → ESTABLISHED
💡 为什么必须三次?
• 防止历史连接干扰:如果第一次握手的包裹卡在路由器(N1/N2)后又重复发送,服务器能通过第三次握手判断是否为过期请求 • 确保双方同步:通过三次握手,双方都能确认对方的发送和接收能力 • 避免资源浪费:防止已失效的连接请求报文突然又传送到服务端,造成错误
✋ 四次挥手过程——例子:快递员确认包裹已全部送达
当数据传输完毕,TCP需要安全断开连接,就像快递员要确认双方都没有包裹需要寄送了:
1. 第一次挥手(浏览器→服务器)
• 动作:
• 浏览器发送FIN=1
(FIN是结束标志),序号seq=5000
• 快递员说:“Chrome的包裹都寄完了,准备收工啦!”
• 状态变化:
• 客户端状态:ESTABLISHED → FIN_WAIT_1
2. 第二次挥手(服务器→浏览器)
• 动作:
• 服务器回复ACK=1
,确认号ack=5001
• 快递员反馈:“好的,我收到你的收工通知了,但等我确认Apache还有没有包裹要寄给你”
• 状态变化:
• 服务端状态:ESTABLISHED → CLOSE_WAIT
• 客户端状态:FIN_WAIT_1 → FIN_WAIT_2
3. 第三次挥手(服务器→浏览器)
• 动作:
• 服务器发送FIN=1
,序号seq=8000
• 快递员说:“Apache这边也没有包裹要寄了,可以收工!”
• 状态变化:
• 服务端状态:CLOSE_WAIT → LAST_ACK
4. 第四次挥手(浏览器→服务器)
• 动作:
• 浏览器回复ACK=1
,确认号ack=8001
• 快递员确认:“双方都确认完毕,连接正式关闭!”
• 状态变化:
• 客户端状态:FIN_WAIT_2 → TIME_WAIT → CLOSED
• 服务端状态:LAST_ACK → CLOSED
💡 为什么挥手要四次?
• 双向关闭原则:TCP是全双工通信,每个方向都需要单独关闭 • 第一次挥手:客户端关闭发送通道 • 第二次挥手:服务端确认客户端的关闭请求 • 第三次挥手:服务端关闭发送通道 • 第四次挥手:客户端确认服务端的关闭请求 • 数据完整性保证:确保双方的数据都能完整传输,不会因为一方提前关闭而丢失数据
🔧 技术细节解析
TCP标志位说明
• SYN(同步序列号):用于建立连接时同步序列号 • ACK(确认标志):表示确认号字段有效 • FIN(结束标志):用于释放连接 • RST(重置连接):用于异常终止连接 • PSH(推送标志):接收方应尽快将这个报文段交给应用层 • URG(紧急标志):表示紧急指针字段有效
序列号与确认号
• 序列号(seq): • 用于标识从TCP源端向目的端发送的字节流 • 初始序列号(ISN)是随机生成的 • 确认号(ack): • 期望收到对方下一个报文段的第一个数据字节的序号 • 计算方式:收到的序列号 + 1
🌐 实际应用场景
1. 网页浏览
• 场景描述: • 打开网页时自动完成三次握手 • 数据传输过程中保持连接 • 关闭标签页时触发四次挥手 • 注意事项: • 现代浏览器通常使用HTTP长连接(Keep-Alive) • 一个TCP连接可以复用于多个HTTP请求
2. 文件下载
• 特点: • 建立连接后持续传输大量数据 • 支持断点续传(基于序列号机制) • 优化建议: • 适当增大TCP窗口大小 • 启用TCP快速重传机制
3. 实时通信
• 应用场景: • 即时通讯 • 在线游戏 • 视频会议 • 性能考虑: • 需要低延迟 • 可能需要配置TCP_NODELAY选项
🛡️ 安全性考虑
1. SYN洪泛攻击
• 攻击原理: • 攻击者发送大量SYN请求但不完成三次握手 • 服务器为每个请求分配资源,最终耗尽资源 • 防护措施: • 启用SYN Cookie • 增大半连接队列 • 设置合理的超时时间
2. TCP重置攻击
• 攻击原理: • 攻击者伪造RST包中断正常连接 • 防护措施: • 启用TCP MD5认证 • 使用IPSec保护TCP连接
3. 连接耗尽攻击
• 攻击原理: • 建立大量TCP连接但不释放 • 防护措施: • 限制单IP的最大连接数 • 启用连接超时机制
🔍 常见问题与解决方案
1. 连接建立失败
• 可能原因: • 网络不通 • 服务端端口未开放 • 防火墙拦截 • 解决方案: • 检查网络连通性 • 确认服务状态 • 检查防火墙规则
2. 连接无法释放
• 可能原因: • TIME_WAIT状态积累 • 程序未正确关闭连接 • 解决方案: • 调整TCP参数(tcp_tw_reuse) • 优化程序代码,确保正确关闭连接
3. 性能问题
• 表现: • 连接建立慢 • 数据传输延迟大 • 优化方案: • 使用TCP Fast Open • 调整TCP缓冲区大小 • 优化网络路由
📚 延伸阅读
- TCP状态转换
- TCP流量控制
- TCP拥塞控制
- TCP keepalive机制
- TCP安全加固最佳实践