很多初学者搞不清 IP、端口、Host(主机头)三者的区别,因为它们都参与了"定位一个资源"的过程。这篇文章用一个寄快递的类比贯穿到底,把三个概念一次讲透。
一、先看一个类比
想象你要寄一封信给住在某个写字楼里的朋友:
| 要素 | 网络中的对应 | 解决的问题 |
|---|---|---|
| XX市XX路XX号(写字楼地址) | IP 地址 | 找到哪台机器 |
| 1503 号房(房间号) | 端口 | 找到机器上的哪个程序 |
| 张三 收(收件人姓名) | Host | 找到这个程序上的哪个站点 |
三层定位,缺一不可。
二、IP 地址:找到哪台机器
IP(Internet Protocol)地址是网络层的概念,它唯一标识了网络中的一台设备(服务器、电脑、手机、路由器等)。
解决的问题:把数据包送到正确的计算机。
两种 IP 版本
IPv4: 192.168.1.1 (32 位,约 43 亿个地址)
IPv6: 240e:390:...:1234 (128 位,几乎无限)IP 的分层:公网 IP vs 私网 IP
互联网
┌──────────┐
│ 8.8.8.8 │ ← 公网 IP(全球唯一)
└──────────┘
│
┌────┴────┐
│ 路由器 │ ← 公网 IP:123.45.67.89
└────┬────┘
│
┌────┴────┐ ┌────┴────┐ ┌────┴────┐
│ PC │ │ 手机 │ │ 服务器 │
│ 192.168.│ │ 192.168.│ │ 192.168.│
│ 1.2 │ │ 1.3 │ │ 1.4 │
└─────────┘ └─────────┘ └─────────┘
私网 IP(局域网内唯一,互联网不可路由)公网 IP 是互联网上的"门牌号",私网 IP 是小区内部的"楼栋号"。
一个 IP 就够了?不够
如果一台服务器只有一个 IP,但上面同时运行着 Web 服务、数据库、SSH 远程登录,数据包到了这个 IP 之后,该交给谁?
这就需要下一层:端口。
三、端口:找到机器上的哪个程序
端口(Port)是传输层(TCP/UDP)的概念,范围是 0~65535。
解决的问题:把数据包交给正确的程序/进程。
端口分类
| 范围 | 类型 | 常见用途 |
|---|---|---|
| 0~1023 | 知名端口(系统保留) | 80(HTTP)、443(HTTPS)、22(SSH)、21(FTP) |
| 1024~49151 | 注册端口 | 3306(MySQL)、6379(Redis)、8080(代理) |
| 49152~65535 | 动态/私有端口 | 客户端临时分配 |
端口与 IP 组合
IP 和端口合在一起写作 IP:端口:
192.168.1.4:80 → 该机器的 Web 服务
192.168.1.4:3306 → 该机器的 MySQL 数据库
192.168.1.4:22 → 该机器的 SSH 登录同一个 IP,不同的端口通向不同的程序。
一个端口对应一个程序就够了?还是不够
现在数据包到了 192.168.1.4:80(Web 服务),但这台服务器上托管了多个网站:
www.example.comblog.example.comapi.example.com
它们都监听 80 端口,请求来了,该返回哪个网站的内容?
这就轮到第三层:Host。
四、Host:找到这个程序上的哪个站点
Host(主机头)是应用层 HTTP/1.1 协议引入的概念,全称是 Host 请求头。
解决的问题:在一台服务器的一个端口上,区分不同的网站。
为什么需要 Host?
在 HTTP/1.0 时代,一个 IP:端口只能托管一个网站。想托管多个网站就得加 IP 或加端口,非常浪费。
# HTTP/1.0 请求(没有 Host)
GET /index.html HTTP/1.0
# 服务器只能根据 IP:端口 确定网站HTTP/1.1 标准引入了 Host 头:
# HTTP/1.1 请求(带有 Host)
GET /index.html HTTP/1.1
Host: www.example.com
# 服务器根据 Host 头确定是哪个网站虚拟主机(Virtual Host)
Nginx/Apache 中的服务器块(server block)正是利用 Host 头来区分不同站点:
# 当 Host 是 www.example.com 时
server {
server_name www.example.com;
root /var/www/example;
}
# 当 Host 是 blog.example.com 时
server {
server_name blog.example.com;
root /var/www/blog;
}
# 当 Host 匹配不到时(默认站点)
server {
server_name _;
root /var/www/default;
}实际抓包演示
当你访问 https://www.3z.ink/articles/网络基础.html 时,浏览器实际发送的请求头是:
GET /articles/网络基础.html HTTP/1.1
Host: www.3z.inkNginx 收到后:
- TCP 层:数据包到达服务器 IP(如 1.2.3.4)
- 传输层:端口 443,交给 HTTPS 服务
- 应用层:Nginx 读取
Host头 →www.3z.ink→ 匹配对应的 server block → 返回对应网站内容
五、三层定位的完整流程
你访问 https://www.example.com:443/page
│
DNS 解析域名 → IP: 93.184.216.34
│
┌───────────────┴───────────────┐
│ │
▼ ▼
IP: 93.184.216.34 Port: 443 (HTTPS)
│ │
│ 找到正确的服务器 │ 找到服务器上的 HTTPS 服务
│ │
└───────────────┬───────────────┘
│
▼
Host: www.example.com
│
在 HTTPS 服务上找到
对应的虚拟主机配置
│
▼
返回网站内容六、HTTPS 的特殊情况:SNI
在 HTTPS 中有一个额外的问题:TLS 握手发生在 HTTP 请求之前。也就是说,在客户端发送 Host 头之前,TLS 握手已经完成了,服务器需要提前知道客户端要访问的是哪个站点,才能出示正确的证书。
解决方案是 SNI(Server Name Indication,服务器名称指示)——在 TLS 握手时就带上域名:
Client Hello
└── server_name: www.example.com这样服务器就能提前知道要访问哪个站点,从而出示对应的 SSL 证书。几乎所有现代浏览器和服务器都支持 SNI。
七、总结
| 概念 | 层级 | 解决的问题 | 类比 |
|---|---|---|---|
| IP 地址 | 网络层 | 把数据送到正确的计算机 | 写字楼地址 |
| 端口 | 传输层 | 把数据交给正确的程序 | 房间号 |
| Host 头 | 应用层 | 把数据交给程序上的哪个站点 | 收件人姓名 |
三者逐层细化定位:
IP(哪台机器) → 端口(哪个程序) → Host(哪个站点)下次遇到多站点部署、反向代理配置、Nginx server_name 匹配等问题时,回想这个三层模型,思路就会清晰很多。