端口号是什么(打电话比喻)
想象一台服务器就是一栋大楼,IP地址是这栋大楼的地址。
大楼里面有很多不同房间,每个房间负责不同业务:
- 3306号房间:MySQL 数据库
- 80号房间:HTTP网页服务
- 6379号房间:Redis缓存
端口号,就是大楼里面各个房间的门牌号。
IP的能力:只能把数据包送到这栋大楼(主机)。
数据包送到大楼之后,操作系统靠端口号,把数据包递交给对应房间里面正在监听的进程。
TCP是端到端通信,端指「进程」。IP找到机器,端口找到机器上的进程。
完整定位标识:IP地址 + 端口号
端口号在TCP里的核心作用
- 区分同一台机器上多个不同的服务进程
一台服务器上同时跑 Nginx、MySQL、Redis。数据包到达主机,如果没有端口号,操作系统不知道这个包该交给哪个程序。 - 标记通信两端的进程
TCP头部里面有源端口、目标端口。
目标端口:你要访问对方哪个房间;
源端口:你自己这边的房间(客户端随机分配的临时端口),对方回复数据的时候,知道要回送到哪个端口。 - 建立TCP连接时的识别标记
服务端进程提前“蹲在端口上监听”(listen),等待客户端TCP连接过来。
PHP fsockopen 为什么必须指定端口
fsockopen是PHP底层创建socket、发起TCP连接的函数。
// 连接MySQL,指定目标IP和端口3306$fp=fsockopen("192.168.1.100",3306,$errno,$errstr,30);- 第一个参数
192.168.1.100:大楼地址(目标主机IP) - 第二个参数
3306:目标房间门牌号(目标端口)
你只给IP不给端口:PHP只知道去哪栋大楼,但不知道要找大楼里哪个房间的服务,连接无法建立。
背后发生的事情
- PHP调用 fsockopen,告诉操作系统:向
192.168.1.100:3306发起TCP连接 - 操作系统内核TCP栈,分配一个随机的本地源端口(客户端临时端口)
- 发起三次握手,目标TCP头部填写目标端口3306,源端口填随机端口
- 远端机器收到IP包,查看TCP头部目标端口=3306,交给MySQL进程
- MySQL回复数据包,回复包的目标端口就是刚才客户端的随机源端口,这样数据才能回到PHP这个进程。
客户端的源端口不用手动指定,操作系统自动分配空闲临时端口,你只需要写目标端口。
两个容易混淆的知识点
- 知名端口(0~1023):固定分配给标准服务,80 HTTP、443 HTTPS、3306 MySQL。服务端一般监听这类端口。
- 动态/临时端口(1024~65535):客户端发起连接的时候,操作系统随机挑选,作为源端口。
误区澄清
- ❌ 端口号是硬件端口(网线口)。
✅ 完全不是。端口号是操作系统内核软件层面的逻辑编号,和物理网线接口无关。 - ❌ 一个端口同一时间可以被多个进程监听。
✅ 不行,同一IP+端口,同一时刻只能有一个进程监听。端口被占用,服务启动失败。 - ❌ TCP端口和UDP端口互相冲突。
✅ TCP端口和UDP端口是两套独立空间。TCP的80端口和UDP的80端口互不干扰。
一句话浓缩
IP地址定位到一台主机,端口号定位主机内部具体的应用进程;PHP fsockopen必须填写目标端口,就是告诉操作系统,要连接目标机器上哪个房间的服务程序。