1. TCP协议概述:它在协议栈里到底扮演什么角色?

聊TCP之前,我先问个问题——你每天上网刷视频、发消息、看网页,数据是怎么从服务器跑到你手机上的?

答案就在TCP/IP协议栈里。我习惯把协议栈比作一个快递系统。应用层是寄件人,网络层是分拣中心,链路层是运输货车。而TCP,就是那个负责把包裹完好无损、按顺序送到你手上的核心调度员。

说白了,TCP工作在传输层,夹在应用层和网络层之间。它不关心你的数据是网页还是视频,它只关心一件事:数据能不能可靠地到达对端。

核心定位:TCP是传输层协议,为应用层提供面向连接的、可靠的、全双工的字节流服务。

TCP在协议栈中的位置

我画了一张图,帮你直观理解TCP的位置。你看,从上到下四层,TCP稳稳地坐在第三层——传输层。

TCP/IP 四层协议栈 应用层(Application Layer) HTTP / FTP / SMTP / DNS / WebSocket 传输层(Transport Layer) TCP(面向连接、可靠) | UDP(无连接、不可靠) 网络层(Network Layer) IP / ICMP / 路由选择 网络接口层(Network Interface Layer) 数据流向 ↑ 上层:用户数据 ↑ TCP:加头部、分段 ↑ IP:加IP头、路由 ↑ 物理:比特流传输

你看,TCP在传输层,上面是应用层,下面是网络层。应用层把数据扔给TCP,TCP负责打包、编号、校验、重传,然后交给IP去发送。IP只管尽力送,不管丢不丢包——可靠性这件事,全靠TCP兜底。

TCP与UDP的区别:一个像快递,一个像飞鸽传书

很多人问我,TCP和UDP到底怎么选?我一般这么解释:

TCP 就像顺丰快递——要签收、要确认、丢了重发、顺序不能乱。适合网页浏览、文件下载、邮件这些不能丢数据的场景。

UDP 就像飞鸽传书——鸽子飞出去就不管了,可能丢了,可能顺序乱了,但速度快啊。适合视频直播、在线游戏、DNS查询这些能容忍少量丢包、但要求低延迟的场景。

我整理了一张对比表,你一看就明白:

对比维度 TCP UDP
连接方式 面向连接(三次握手) 无连接
可靠性 可靠传输、确认重传 不可靠,尽力交付
数据顺序 保证有序到达 不保证顺序
传输方式 字节流 数据报(有边界)
头部开销 20~60字节 8字节
流量控制 支持(滑动窗口) 不支持
拥塞控制 支持(慢启动、拥塞避免) 不支持
典型应用 HTTP、FTP、SMTP、SSH DNS、VoIP、视频直播、游戏

我的经验:做实时音视频项目时,我一开始用了TCP,结果卡得不行。后来换成UDP + 应用层FEC(前向纠错),延迟从200ms降到了30ms。选TCP还是UDP,核心看你的业务对可靠性和实时性的权衡。

TCP的核心特性:三个关键词

TCP之所以能成为互联网的基石,靠的就是这三个特性。我一个个说。

1. 面向连接

TCP通信之前,必须先建立连接。这个连接不是物理线路,而是逻辑上的虚拟连接。双方通过三次握手,协商初始序列号、窗口大小、MSS等参数,然后才开始传数据。

我曾经排查过一个线上问题:客户端频繁报连接超时。抓包一看,三次握手的SYN包发出去了,但服务器没回SYN-ACK。最后发现是服务器端的半连接队列满了——面向连接意味着有状态,有状态就意味着资源消耗。这个坑后面章节会细讲。

2. 可靠传输

TCP的可靠性不是吹的,它用了一套组合拳:

  • 确认应答(ACK):每收到一个数据段,接收方都要回复ACK
  • 超时重传(RTO):发送方没收到ACK,就重传
  • 序列号与排序:每个字节都有编号,接收方按序组装
  • 校验和:检测数据是否损坏
  • 去重:重复的数据包会被丢弃

说白了,TCP用确认 + 重传 + 序号这三个机制,把不可靠的IP网络包装成了一个可靠的管道。你想想看,如果没有TCP,你下载文件时丢一个包,整个文件就坏了——这谁能忍?

3. 全双工通信

TCP连接建立后,双方可以同时发送和接收数据。不像对讲机,你一句我一句,得等对方说完才能说。TCP是电话——你可以同时说话和听。

这个特性很重要。比如你在浏览器里请求一个网页,浏览器发送HTTP请求的同时,服务器也在推送数据回来。如果TCP是半双工的,那效率得砍一半。

全双工的本质:TCP连接的两端各自维护一个发送缓冲区和一个接收缓冲区。发送方只管往缓冲区写,TCP协议栈负责把数据发出去;接收方从缓冲区读,TCP协议栈负责把数据按序放好。读写互不干扰。

一个简单的TCP通信流程

我画个流程图,把上面三个特性串起来:

TCP通信流程(三次握手 + 数据传输 + 四次挥手) 客户端(Client) 服务器(Server) 三次握手(建立连接) ① SYN(seq=x) ② SYN-ACK(seq=y, ack=x+1) ③ ACK(seq=x+1, ack=y+1) 连接建立成功 数据传输(全双工) 数据段(seq=x+1, 含HTTP请求) ACK(ack=...) 数据段(seq=y+1, 含HTTP响应) 四次挥手(断开连接) ① FIN(seq=u) ② ACK(ack=u+1) ③ FIN(seq=v) ④ ACK(ack=v+1)

注意:三次握手和四次挥手是TCP面试的必考题,也是排查网络问题的基本功。我见过太多人背了流程但不懂原理——比如为什么握手是三次而不是两次?为什么挥手是四次而不是三次?这些问题后面章节会深入拆解。

小结一下

这一章我们聊了TCP在协议栈中的位置、TCP与UDP的区别、以及TCP的三个核心特性。嗯,内容不算多,但都是基础中的基础。

我个人习惯把TCP理解成一个可靠的、有序的、全双工的管道。你往这头写数据,对端从那头读数据,中间的一切——丢包、乱序、拥塞、流量控制——TCP都帮你处理好了。