主题
22 · 套接字、端口与网络栈直觉
目标:把
ss/curl/Nginx 反代映射到 socket 与端口,建立网络栈分层直觉(不深挖协议细节)。
命令行前置:05、09、10。
1. 环境前提
- 若有 mini-api / nginx 更佳;没有也能看 SSH(22) 与本机回环
bash
mkdir -p ~/lab/os1
2. 概念框(轻量课本)
| 词 | 一句话 |
|---|---|
| 套接字(socket) | 进程与网络栈之间的通信端点;在 Linux 上也是一种可放进 fd 表的对象 |
| 端口 | 主机上区分「哪个服务」的 16 位编号(TCP/UDP 各自一套) |
| 监听(LISTEN) | 服务在某地址:端口上等连接 |
| 已连接 | 一对四元组(本机IP:端口 ↔ 对端IP:端口)上的会话 |
分层直觉(只记名字):
text
应用(curl / nginx / mini-api)
→ socket API(syscall)
→ TCP/UDP
→ IP
→ 网卡驱动1
2
3
4
5
2
3
4
5
反代心智(09~10):
text
客户端 → :80(Nginx 监听) → 本机 127.0.0.1:8080(应用监听)1
两个 socket:Nginx 对外一个、对内 upstream 再一个。
3. 动手:ss 与对照
bash
sudo ss -tulpn
sudo ss -tulpn | grep -E ':80|:8080|:22' || true1
2
2
| 状态 | 含义 |
|---|---|
LISTEN | 在听 |
ESTAB | 已建立连接 |
边 curl 边看:
bash
# 终端 A
curl -sS -o /dev/null http://127.0.0.1/
# 终端 B(几乎同时)
sudo ss -tn | head
sudo ss -tnp | grep curl || true1
2
3
4
5
2
3
4
5
看进程的 socket fd(有服务时):
bash
PID=$(pgrep -n nginx || pgrep -n mini-api || true)
if [[ -n "${PID}" ]]; then
ls -l /proc/"$PID"/fd | head
# 类型为 socket: 的就是套接字
fi1
2
3
4
5
2
3
4
5
strace 回看(16 篇):
bash
strace -e trace=network curl -sS -o /dev/null http://127.0.0.1/ 2>&1 | head -n 301
4. 与命令行篇对照
| 05 / 09 / 10 | OS 视角 |
|---|---|
ss -tulpn | 枚举 socket 与 inode,再映射到进程 |
应用绑 127.0.0.1:8080 | 只在回环接口上建监听 socket |
Nginx proxy_pass | 作为客户端再 connect 到上游 |
| ufw 放行 80 | 包过滤在更外层;应用仍须 listen |
5. 动手清单
- [ ]
ss -tulpn指出至少一个 LISTEN 行及其进程 - [ ] 口述:端口与 PID 的关系(谁占用)
- [ ] 画出「公网 80 → Nginx → 127.0.0.1:8080」两个监听点
- [ ] (可选)
strace -e trace=network看到socket/connect
6. 常见翻车
| 翻车 | 处理 |
|---|---|
| 进程在但端口未听 | bind/listen 失败或听错地址 |
| 只放行安全组未 listen | ss 无 LISTEN |
| 以为「端口=进程」 | 端口是 socket 上的属性;进程通过 fd 持有 socket |
7. 官方 / 延伸
man ss、man 7 ip、man 7 tcp- ss(8)
下一篇:信号、中断与进程如何结束 —— 阶段 C 收束。
