SSH / Tmux / SCP 全链路详解服务器内部视角一、SSH 登录远程服务器内部发生了什么1️⃣ 常驻监听远程服务器启动后系统中常驻一个sshd 主进程socket(AF_INET, SOCK_STREAM, 0); // 创建 TCP 接口 bind(port22); // 绑定 22 号端口 listen(); // 持续监听监听者sshd主权限root职责只负责“接电话”2️⃣ 你发起连接fork 出子进程当你在本地执行ssh userserver服务器内部TCP 三次握手完成sshd主调用fork();生成一个sshd(子)专门服务你这一条连接主进程继续监听别人3️⃣ sshd(子) 申请 PTY伪终端sshd(子)向Linux 内核申请终端open(/dev/ptmx);内核创建PTY一对名称作用PTY Master网络端sshd 用它写/读PTY Slave终端端bash 看到的“假屏幕”4️⃣ fork exec 出 bashsshd(子)再 fork 一次fork(); exec(/bin/bash);结果sshd(子) └── bash ├── stdin → PTY Slave ├── stdout → PTY Slave └── stderr → PTY Slave5️⃣ 你输入命令时发生了什么python train.py流程本地 SSH client → TCP → sshd(子)sshd(子) 写入 PTY Master内核 → PTY Slavebash 读到命令bashfork()→exec(python)python使用CPU / 内存通过CUDA​ 调用GPU读写远程磁盘输出原路返回python → PTY Slave → PTY Master → sshd(子) → TCP → 本地屏幕二、断网后为什么普通 SSH 会死1️⃣ 断网瞬间TCP 连接断开sshd(子)发现网络 EOFsshd(子)退出PTY Master 被关闭2️⃣ 内核发 SIGHUP内核发现“PTY 的控制端Master没了”于是向会话首进程bash​ 发送SIGHUPbash 默认终止bash 向前台进程组python转发 SIGHUPpython 退出3️⃣ PTY 被回收bash 关闭 PTY Slave无人引用 PTY内核回收 PTY✅这就是“一断网训练全没”的根本原因三、Tmux为什么断网后还能活着1️⃣ Tmux 做了什么你在 SSH 里输入tmux new -s train服务器内部bash fork → exec →tmux clienttmux client fork →tmux servertmux server被systemd/init收养PPID1不依赖 sshd(子)tmux server自己申请 PTYfork → bashtmux 内 bashtmux client通过Unix Socket​ 连接 tmux server充当 sshd(子) 与 tmux server 的桥梁2️⃣ 断网时发生了什么组件命运sshd(子)退出tmux client退出tmux server✅ 活着tmux PTY✅ 开着bash✅ 活着python✅ 继续跑✅因为 tmux server 的父不是 sshd而是系统 init四、SCP为什么不能只用 SSH1️⃣ SSH 的局限SSH 只能执行远程命令传输终端 IO❌不能把本地文件“变”到远程磁盘2️⃣ SCP 的原理SCP 本质是基于 SSH 加密通道的“文件复制工具”执行scp train.py userserver:/home/user/内部流程本地 scp打开train.py读文件内容通过 SSH 通道发送远程 sshd启动临时 scp 进程把数据写成/home/user/train.pySCP 传的是“文件数据”不是命令3️⃣ SSH vs SCP 一句话区别工具传什么用途SSH命令字符远程执行SCP文件内容远程存文件