拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

第 6 天|IP 把数据送到机器,谁把它交给程序

第 6 天|IP 把数据送到机器,谁把它交给程序

前五篇,我们一直在追一份数据包:它离开电脑,经过路由器,一跳一跳走向服务器。

假设它终于到了。服务器上可能同时运行着网站、数据库和其他服务;网站还可能正在接待成千上万名访客。服务器怎么知道,这份数据该交给哪个程序、哪个访客的连接?

答案要从端口说起。弄懂端口,再看 TCP 和 UDP,就能明白它们为什么都属于“传输层”,却提供了不同的服务。

IP 地址只能找到机器

把服务器的 IP 地址想成一栋楼的地址,大体上是有用的:数据可以靠它找到目标机器。但数据到了楼下,还得知道交给谁。

端口就是操作系统分配和识别网络通信的一种编号。比如,一个网站服务可能在 TCP 的443端口等待连接。

假设你的电脑向网站发起一次连接:

你的电脑 192.168.1.20:53142 ↓ 网站服务器 203.0.113.10:443

冒号前是 IP 地址,冒号后是端口号。这里:

  • 203.0.113.10指向目标服务器;
  • 443指向服务器上等待这类连接的服务;
  • 53142是电脑为这次通信使用的本地端口,便于接收返回的数据。

服务器回复时,方向反过来:

网站服务器 203.0.113.10:443 ↓ 你的电脑 192.168.1.20:53142

如果你记得前一篇的 NAT:数据经过家用路由器时,来源 IP 和来源端口可能被改写。上图画的是电脑这一侧看到的通信信息,不代表互联网上每一跳看到的来源地址都完全一样。

端口也不是机器上真实存在的插孔。它是网络协议中的编号,由操作系统用来把收到的数据交给相应的网络程序。

同一个443,怎么接待许多访客?

服务器上的网站可以一直在443端口等待连接,并不需要为每个访客换一个服务端口。

来看两位访客:

访客 A 192.168.1.20:53142 → 服务器 203.0.113.10:443 访客 B 192.168.1.21:53142 → 服务器 203.0.113.10:443

两台设备甚至碰巧用了相同的本地端口。服务器仍然能区分,因为来源 IP 不同。即使同一台电脑打开多个连接,也可以使用不同的本地端口。

对于 TCP 连接,常用下面四项描述通信双方:

来源 IP + 来源端口 + 目标 IP + 目标端口

再加上使用的是 TCP 还是 UDP,就能区分不同协议中的通信。这比单说“连接了 443 端口”准确得多:端口必须放在 IP 地址和传输协议的上下文里看。

你可以把“服务器监听443”理解为它开着一个接待入口;进入后的每条通信,操作系统仍然能分清是谁和谁在说话。

为什么还需要 TCP 或 UDP?

IP 负责寻址和转发,但它并不承诺每个数据包都能到达,也不承诺先发的包一定先到。

应用程序对传输的要求却不一样。传一份文件时,你希望内容完整、顺序正确;进行实时通话时,迟到几秒的旧声音可能已经没有用,应用更关心及时处理当前声音。

TCP 和 UDP 给应用提供了两种不同的基础。它们都使用端口,但处理数据的方式不同。

UDP:按一份一份的消息发送

UDP 提供的是数据报服务。应用交给它一份消息,它把这份消息作为一个数据报发送。接收方如果收到了,也能按一份数据报来处理。

UDP 本身不先建立 TCP 那样的连接,也不负责替应用保证送达、按序到达或丢失后重传。它做得少,给上层留下了更多选择。

这并不等于“使用 UDP 的应用不可靠”。应用可以自己决定怎样确认、重传或纠错。QUIC 就建立在 UDP 之上,另外实现了连接管理、可靠传输等能力,HTTP/3 使用的正是 QUIC。

所以,更准确的说法是:

UDP自身不提供可靠、有序的传输;使用 UDP 的上层协议可以按需要补上这些能力。

DNS 查询常使用 UDP,但 DNS 也可以使用 TCP。实时音视频也常采用基于 UDP 的方案。不能看见“UDP”两个字,就断定它一定是游戏或语音,更不能断定它“一定比 TCP 快”。实际速度还取决于应用要实现什么、网络状况如何,以及丢包后怎么处理。

TCP:建立连接,交付有序的字节流

TCP 提供的是另一种服务:可靠、有序的字节流。

通信双方先建立连接。传输过程中,TCP 会处理编号、确认、重传等问题,努力把发送方交出的字节按顺序交给接收方。下一篇会专门拆开讲建立和关闭连接,第八篇再讲它怎样处理丢包与拥塞。

这里有个很容易被忽略的词:字节流。

假设程序连续写入两次:

第一次写入:“你好” 第二次写入:“世界”

接收方不能想当然地认为,自己一定会收到两份恰好对应的“消息”。它可能一次读到“你好世界”,也可能分几次读到。TCP 保证的是字节顺序,不替应用规定“第一条消息在哪里结束,第二条在哪里开始”。

如果应用需要区分一条条消息,就得自己设计边界,例如先写明消息长度,或者约定分隔方式。HTTP 等应用层协议要处理的,正包含这类“这些字节是什么意思”的问题。

TCP 的“可靠”也有边界。它能确认数据在连接中被另一端的 TCP 接收,不等于网站已经把订单写入数据库,更不等于用户重复点击付款时业务只会执行一次。传输成功和业务成功,不是一回事。

到底该用哪个?

把两者放在一起看,区别就清楚了:

问题TCPUDP
发送前是否建立传输连接?是否
是否由协议自身处理有序、可靠传输?是否
交给应用的是什么?连续的字节流一份份数据报
丢包后的处理TCP 有确认和重传机制由使用它的上层协议决定

选用哪个,不是按“TCP 稳、UDP 快”二选一。要看应用究竟需要什么,以及它愿意自己承担多少传输工作。

访问网页就是一个好例子。很多 HTTPS 连接运行在 TCP 之上;HTTP/3 则使用建立在 UDP 之上的 QUIC。用户看到的都是网页,但底层传输方案可以不同。443也不能脱离 TCP 或 UDP 单独理解:TCP443和 UDP443是不同协议中的端口。

在电脑上看见真实连接

Windows 用户可以打开几个网页,再在命令提示符中输入:

netstat -ano -p tcp

在输出中找状态为ESTABLISHED的行。你可能看到类似内容:

协议 本地地址 外部地址 状态 PID TCP 192.168.1.20:53142 203.0.113.10:443 ESTABLISHED 1234

这是示意,不是你电脑应当出现的固定地址。试着辨认本地 IP、本地端口、远端 IP、远端端口。最后一列 PID 是进程编号。

再运行:

netstat -ano -p udp

你会发现 UDP 的显示方式与 TCP 连接列表不同:UDP 没有ESTABLISHED这种 TCP 连接状态。

如果你刚打开了网页,却没找到对应的 TCP443,先别急着判断命令失效。浏览器可能使用了 HTTP/3,也可能复用了已有连接;连接还可能很快结束。这个练习的重点,是读懂一行连接信息,而不是保证抓到某个指定网站。

今天把从“机器”到“程序”的最后一步补上了:IP 帮数据找到目标设备,端口帮助设备区分通信;TCP 和 UDP 决定应用拿到怎样的传输服务。

下一篇,我们顺着最常见的 TCP 连接继续问:既然要先建立连接,为什么大家总说“三次握手”?关闭连接时又发生了什么?

参考资料:TCP 规范 RFC 9293、UDP 规范 RFC 768、QUIC 规范 RFC 9000、微软netstat使用说明。

返回列表