服务器通信的本质,是遵循既定协议的进程间数据交换。它不靠玄学,靠的是IP地址、端口和协议这三要素的紧密配合。
服务器之间怎么通信:先看懂三要素
两台服务器要“对话”,第一步是找到对方,这个过程和寄快递极其相似。
IP地址:服务器的门牌号
每台服务器在网络上都有一个唯一标识,叫IP地址,IPv4地址类似168.1.10,IPv6则是一长串十六进制字符,发送方把数据包丢给这个门牌号,路由器就负责沿途接力,把包裹送对地方,行业共识认为,IP地址解决的是“去哪台机器”的问题。
端口:进程的房间号
机器找到了,但机器上跑着Web服务、数据库服务、缓存服务等多个程序,数据包该交给谁?端口号来定,默认情况下,HTTP走80,HTTPS走443,MySQL走3306,Redis走6379。IP加端口,才能精确定位到具体进程。
协议:双方共同的语言
有了地址和房间,双方还得说同一种语言,TCP/IP协议族就是互联网的通用语,其中TCP提供可靠、按序的字节流传输,文件传输、网页访问都靠它;UDP则追求低延迟、不保证送达,适用于直播、DNS查询,选错协议,要么慢,要么丢。
服务器通信原理:从TCP三次握手说起
HTTP请求本质上跑在TCP之上,一次完整通信,必然经历三次握手和四次挥手。
三次握手:建立可靠连接
- 客户端发送SYN包(请求同步),进入SYN_SENT状态。
- 服务端收到后回复SYN+ACK包(同步+确认),进入SYN_RCVD状态。
- 客户端再回一个ACK包(确认),连接正式建立,双方进入ESTABLISHED状态。
用大白话说:“你听得到吗?”“听得到,你听得到吗?”“我也听得到,开始干活。”

这三次交互,确保双方的收发能力都没问题,很多服务器通信故障,都是卡在这一步要么被防火墙丢包,要么半连接队列溢出。
数据交互与滑动窗口
连接建立后,数据不是一发就完,TCP通过滑动窗口做流量控制,窗口大小决定对方一次能发多少数据,如果接收方处理慢,窗口就变小,发送方就得减速。拥塞控制则根据网络拥堵程度动态调整发包速率,避免全网瘫痪。
四次挥手:优雅地告别
断开连接需要四次交互:
- 主动方发FIN包:“我说完了。”
- 被动方回ACK包:“知道了,我还在收尾。”
- 被动方再发FIN包:“我也说完了。”
- 主动方回ACK包:“好的,再见。”
TIME_WAIT状态会保留一段时间用于兜底丢包,这也是高并发服务器经常出现大量TIME_WAIT的原因之一。
服务器通信方式:同步阻塞与IO多路复用
理解了基础流程,还得知道在工程上服务器怎么扛住成千上万个并发连接。
传统BIO:一连接一线程
早期做法是每个连接分配一个线程,连接少还好,连接一多,线程上下文切换开销直接拖垮CPU,近年来在常见高并发业务中,这种模型已被逐步替换。
NIO与IO多路复用:单线程管万连接
NIO(非阻塞IO)配合多路复用器(select/poll/epoll),让单个线程同时监视成百上千个连接的事件状态,Linux平台下,epoll是扛住高并发的关键工具,Nginx、Netty、Redis底层都依赖这个机制。
事件驱动与Reactor模型
主流高并发服务器采用Reactor模型:
-

主线程
只负责监听新连接,accept之后注册到子线程。 - 工作线程处理实际的数据读写和业务逻辑。
- 一套线程池加事件循环,就能支撑十几万并发。
同理,Java中的Netty框架、Node.js的事件循环也遵循类似路径,它解决的问题是:线程不能被连接数绑架,资源要按事件动态分配。
服务器通信协议对比:TCP、UDP与HTTP
不同业务场景,协议的选型差异巨大,下表可作为基础参考:
| 比较维度 | TCP | UDP | HTTP/3 |
|---|---|---|---|
| 连接状态 | 有连接,状态厚重 | 无连接,发完即走 | 基于QUIC,兼顾可靠与低延迟 |
| 数据可靠性 | 保证送达且有序 | 不保证,靠应用层兜底 | 自动恢复丢包 |
| 典型场景 | 网页、文件、数据库 | 语音通话、直播、DNS | 移动弱网环境、API服务 |
| 运维难度 | 需要操心调优参数 | 相对简单但要做丢包补偿 | 对CDN和后端网关有要求 |
选型建议:
- 追求绝对可靠,选TCP。
- 对延迟极度敏感,且能容忍少量丢失,选UDP。
- 面向移动网络或弱网,近年普遍建议跟进HTTP/3(基于QUIC)的落地。
服务器通信故障怎么排查?实操路径
第一步:检查端口监听状态
使用ss -anp | grep 8080查看端口是否被监听,没监听,应用可能没起来;有监听但连不上,查防火墙。
第二步:测试TCP连通性
用telnet 目标IP 端口

做一次粗略探测,卡住不动基本是被防火墙DROP了;显示Connected则网络链路正常,问题大概率出在应用层。
第三步:抓包看三次握手
tcpdump -i eth0 host 目标IP and port 8080是经典命令,主要看:
- 只有SYN发出,没有SYN+ACK回来出方向或对端入方向被拦截。
- SYN+ACK发出,但客户端不回ACK客户端侧问题或半连接队列满。
- 握手正常,但后续数据重传频繁网络丢包严重或拥塞窗口设置过小。
第四步:检查应用层超时与队列
高并发下,ss -lnt的Send-Q和Recv-Q会显示队列堆积情况,Recv-Q常年很大,意味应用层读数据太慢,配合监控CPU、GC日志(Java场景)、线程池活跃度,基本能定位瓶颈。
服务器通信机制常见问题
一台服务器最多能建立多少个TCP连接?
理论值由文件符上限和内存决定。服务端单机百万连接在调优后是可行的,但客户端通常受限于端口数量,单IP最多约6.5万个四元组组合。
服务器之间通信,公网IP和内网IP有区别吗?
别的,内网通信走交换机,延迟低、带宽高,不经过公网NAT,适合大数据交互,但跨地域、跨机房通信就得走公网或专线,此时传输加密和鉴权必须到位。
为什么高并发场景下偶尔出现大量TIME_WAIT连接?
TIME_WAIT是主动关闭方为保证最后一个ACK不丢而保留的兜底状态。连接主动断开的这一侧会积累大量TIME_WAIT,通过开启tcp_tw_reuse合理复用,或让客户端主动断开连接,可有效缓解,据网络运维领域的长期观察,这是业内高并发调优中最常见的处理路径之一。