到底什么是 TCP 连接?
- 标签:网络
🏛 业务架构师
TCP 连接的本质是通信双方内核里维护的一组状态:源 IP、源端口、目的 IP、目的端口组成的四元组标识一条连接,配对每端的发送/接收缓冲区、序号与窗口状态机。它不对应任何物理线路——"连接"是两端共同维护的逻辑契约:双方就"序号从哪开始、接收窗口多大、哪些数据已确认"达成并持续更新共识。
业务视角,把连接当有成本的资源来经营:
- 四元组决定容量上限:客户端单 IP 可用端口约 2.8 万(一个 IP 对同一目标只有一个端口空间)——高频外呼系统(短信网关、爬虫、回调)的端口耗尽是真实容量问题,解法:连接池复用、多出口 IP、HTTP/2 单连接多路复用;
- 服务端上限是文件描述符 + 内存:fd 数、每连接缓冲区内存、C10K/C1000K 的调优(somaxconn、文件句柄),连接容量规划是容量评审的必填项;
- 连接数是成本仪表盘:established 异常上涨=下游变慢(连接堆积);CLOSE_WAIT 堆积=应用没关连接的 bug;TIME_WAIT 暴涨=短连接风暴——每个状态都是一种业务信号的投影;
- 连接的建立与维护都有价格:握手 RTT、keepalive 探测包、NAT 映射表老化(移动网络长连接要心跳维持 NAT 映射,IM 心跳间隔是省电与保活的权衡)。
一句话:TCP 连接是"两台机器关于数据顺序与状态的共识",架构师的工作是管好这份共识的成本——复用、池化、按业务分配连接预算。
🏗 系统架构师
TCP"连接"不是一根物理线路,而是通信双方各自维护的一组状态数据结构:四元组(源 IP、源端口、目的 IP、目的端口)+ 双方各自保存的发送缓冲区、接收缓冲区、序列号/确认号、滑动窗口、拥塞控制参数(cwnd/ssthresh)等。所谓"建立连接",就是通过三次握手协商并初始化这套状态,让双方对初始序列号达成一致;所谓"断开",就是协商释放这些资源。
几个关键认识:
- 连接是逻辑概念,网络上只有报文流动,中间路由器不感知连接(无状态转发);
- 服务端能同时维持海量连接,靠的是四元组唯一区分:服务端 80 端口可以有几万个"连接",每个客户端 IP/端口组合不同;受限制的是端口范围(客户端出站约 2.8 万可用端口/目标)与文件描述符、内存(每连接缓冲区);
- "断连"检测:靠 keepalive 探测(默认 2 小时太长,应用层心跳 15~30 秒更实际),因为 TCP 对静默断电、网线拔掉是无感知的——这是我做长连接网关时必答的细节;
- 短连接风暴的本质:连接创建/销毁的状态机开销(握手、TIME_WAIT 资源占用)。
一句话总结:TCP 连接 = 两端关于"如何可靠对话"的共识状态,报文只是维持与推进状态机的输入。
💻 全栈开发专家
TCP 连接不是一根"线",而是通信双方内核里的一组数据结构 + 状态机,用**四元组(源IP、源端口、目的IP、目的端口)**唯一标识。
两端各自维护:
- 发送/接收缓冲区(未确认数据、待应用读取的数据);
- 序列号与确认号(字节流的位置同步);
- 状态机(ESTABLISHED、TIME_WAIT 等 11 种状态);
- 拥塞窗口、滑动窗口等控制变量。
所以"建立连接"本质是双方通过三次握手协商初始序列号,把各自的数据结构初始化到 ESTABLISHED;"断开"是状态机的协商回收。物理上只有数据包在飞,没有任何专线——这就是为什么连接可以被"半开"检测(keepalive)、可以 RST 强断。
工程视角(这题的实用价值):
- "端口耗尽"的真相:客户端作为主动方,四元组里只有源端口可变,理论上限 = 目的端口数 × 目的 IP 数 × 源 IP 数;对同一目标 (ip:port) 最多约 65535 - 1024 个连接。我压测时遇到过,解法:多源 IP(VIP)、长连接复用;
- 服务端一个监听端口可以承载百万连接(fd 数量限制才是关键,
ulimit -n、somaxconn),"65535 端口所以最多 6 万连接"是经典误解; - 排查连接状态用
ss -tan:看 ESTABLISHED/TIME_WAIT/CLOSE_WAIT 分布,直接反映应用健康度。