1. 端口基础概念:什么是端口、TCP/UDP端口号范围、常见端口服务映射表

各位同学好,我是老赵。今天咱们开始《端口占用问题排查实战》的第一章。

端口这东西,说白了就是计算机和外界通信的「门牌号」。你想想看,一台服务器上跑着 Web 服务、数据库、邮件服务……数据包来了,系统怎么知道该交给谁?

嗯,就是靠端口号。

1.1 什么是端口?

端口是一个 16 位的数字标识符,范围从 0 到 65535。它和 IP 地址一起,构成了网络通信的「终点」。

我习惯用一个比喻:IP 地址是小区地址,端口号就是单元门牌。快递员(数据包)到了小区(服务器),还得知道具体几单元几号(端口),才能把东西送到你手上(对应进程)。

核心公式:

套接字(Socket)= IP 地址 + 端口号

一个完整的网络连接,由「源 IP + 源端口 + 目标 IP + 目标端口 + 协议」五元组唯一确定。

我在项目中遇到过不少新手,一上来就问「端口被占用了怎么办?」。其实你先得搞清楚:端口是操作系统分配给进程的资源。一个端口同一时间只能被一个进程监听,这就是冲突的根源。

1.2 TCP/UDP 端口号范围

端口号分三段,IANA(互联网数字分配机构)划的。我整理了一张表,大家记牢:

分类 范围 说明 举个栗子
Well-Known(知名端口) 0 – 1023 系统特权端口,需要 root/admin 权限才能绑定 HTTP(80)、HTTPS(443)、SSH(22)
Registered(注册端口) 1024 – 49151 用户进程或常见应用使用,IANA 登记过 MySQL(3306)、Redis(6379)、Docker(2375)
Dynamic/Private(动态/私有端口) 49152 – 65535 临时端口,客户端发起连接时随机分配 浏览器访问网页时用的临时端口

避坑指南:我曾经在排查一个生产故障时,发现应用绑定了 1024 端口,结果普通用户启动直接报「权限不足」。后来才意识到,1024 以下归系统管。所以自定义服务端口,我建议选 1024 以上的注册端口范围,比如 8080、8443 这些。

1.3 TCP 与 UDP 端口有什么区别?

很多同学会问:TCP 端口和 UDP 端口是分开的吗?

答案是:端口号空间是共享的。TCP 的 80 端口和 UDP 的 80 端口是两个不同的逻辑通道,可以同时被不同进程使用。

我画了一张图,帮大家理解这个关系:

TCP/UDP 端口号空间与协议栈关系 Web 服务 (Nginx) DNS 服务 (BIND) 数据库 (MySQL) 传输层协议 TCP 协议(面向连接、可靠) UDP 协议(无连接、快速) 端口号空间(0 – 65535) 知名端口 (0-1023) 注册端口 (1024-49151) 动态端口 (49152-65535)

从图上可以看明白:应用层进程选择使用 TCP 还是 UDP,然后绑定到具体的端口号。比如 Nginx 用 TCP 80 端口,DNS 用 UDP 53 端口,两者互不干扰。

注意:虽然 TCP 和 UDP 端口空间独立,但大部分操作系统不允许同一个进程同时用 TCP 和 UDP 监听同一个端口号(除非显式设置 SO_REUSEADDR)。我曾经见过一个案例,有人想用同一个端口跑 TCP 和 UDP 服务,结果启动时报「Address already in use」——嗯,踩坑了。

1.4 常见端口服务映射表

这张表我建议你收藏。排查问题时,看到端口号就能猜到是什么服务,效率翻倍。

端口号 协议 服务名称 说明
21 TCP FTP 文件传输协议(控制通道)
22 TCP SSH 安全外壳协议,远程登录
23 TCP Telnet 远程登录(明文,不推荐)
25 TCP SMTP 简单邮件传输协议
53 TCP/UDP DNS 域名系统
80 TCP HTTP 超文本传输协议
110 TCP POP3 邮局协议第3版
143 TCP IMAP 互联网消息访问协议
443 TCP HTTPS HTTP over TLS/SSL
3306 TCP MySQL MySQL 数据库
5432 TCP PostgreSQL PostgreSQL 数据库
6379 TCP Redis Redis 缓存数据库
8080 TCP HTTP-Alt HTTP 备用端口(Tomcat 等)
27017 TCP MongoDB MongoDB 数据库

个人经验:我习惯在服务器上放一个 /etc/services 的备份,或者直接用 grep 端口号 /etc/services 快速查。Linux 系统自带的这个文件记录了大部分知名端口,比上网查快多了。

1.5 端口与进程的关系

端口本身只是一个数字,真正干活的是进程。操作系统维护着一张「端口 → 进程」的映射表。当数据包到达时,内核根据目标端口号,把数据交给对应的进程。

我常用一个命令来查看这种对应关系:

# Linux 查看端口与进程对应关系
netstat -tlnp

# 或者用 ss 命令(更快)
ss -tlnp

# 输出示例:
# Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
# tcp   0      0      0.0.0.0:80              0.0.0.0:*               LISTEN      1234/nginx
# tcp   0      0      0.0.0.0:22              0.0.0.0:*               LISTEN      567/sshd

看到没?80 端口对应 PID 1234 的 nginx 进程,22 端口对应 PID 567 的 sshd 进程。这就是端口占用的直接证据。

避坑指南:我曾经遇到一个情况,netstat 显示端口被占用,但 PID 列是「-」。后来发现是进程已经挂了,但端口还没释放(TIME_WAIT 状态)。这时候别慌,等一会儿或者用 SO_REUSEADDR 选项重启服务就行。

1.6 本章小结

好了,第一章的内容就这些。总结三个要点:

  • 端口是进程的网络门牌号,0-65535 分三段,1024 以下需要 root 权限。
  • TCP 和 UDP 端口空间独立,但同一个端口号不能同时被两个进程监听(同一协议下)。
  • 常见端口要记熟,排查问题时一眼就能认出服务。