rz、sz 上传下载文件的工作原理
通过ssh登录到远程主机,想要上传和下载文件,最方便的方式就是rz和sz命令了,如果你的系统里没有这两个命令,需要先安装 lrzsz 软件包。
查看 man 手册,可以看到相关的几个命令:
sx, sb, sz - XMODEM, YMODEM, ZMODEM file send
rx, rb, rz - XMODEM, YMODEM, ZMODEM (Batch) file receive
s 是 send,r 是 receive,这是在远程主机的角度理解的。比如在远程主机执行 rz ,代表了远程主机是接收方(receive)本机是发送方。后一个字母代表的是文件传输协议,那么问题来了,什么是XMODEM, YMODEM, ZMODEM ,它们是怎么工作的 ?
传输文件的过程中,你会发现终端是不能使用的,如果中间出现问题,终端还会被卡死,这又是为什么?
先来看看虚拟终端是怎么工作的。


如上图,在终端中打开vim程序,其文件描述符0,1,2分别代表标准输入,标准输出,标准错误输出。结果就是把终端的输入输出通过ssh协议建立的一个tty通道绑定到vim程序上。
那么当我们使用rz或sz时发生什么呢?
新开一个终端窗口:

可以很明显地看到,rz命令除了除了读写磁盘上的文件,就剩下和终端的标准输入输出通信了。也就是说ZMODEM就是利用终端的标准输入和输出通道传文件。在客户端,我们的标准输入输出被临时交给了ZMODEM程序,正因为如此,终端就不能使用了。

XMODEM 是1977年 Ward Christensen 在一个叫MODEM.ASM的虚拟终端程序上实现的,后来经过改进,出现了YMODEM、ZMODEM,它们只是改进了交互过程的协议,但都是在tty的标准输入输出通道上运行的。到底用哪个协议,主要看你的服务器和虚拟终端支持哪种协议。新系统和终端应该都支持ZMODEM了。
他们的协议也是利用了能在终端传输的ASCII的控制字符,XMODEM协议最简单,以它为例,XMODEM使用了这些字符(使用CRC 数据校验的模式):
| 字符 | 描述 | 值 |
|---|---|---|
| SOH | Start of Header 头部开始 | 0x01 |
| SUB | Substitute 补全数据长度 | 0x1a |
| EOT | End of Transmission 传输结束 | 0x04 |
| ACK | Acknowledge 应答 | 0x06 |
| NAK | Not Acknowledge 非应答 | 0x15 |
| ETB | End of Transmission Block (Return to Amulet OS mode) 传输块结束 | 0x17 |
| CAN | Cancel (Force receiver to start sending C's)撤销 | 0x18 |
| C | ASCII “C” 字母C ,代表CRC数据校验 | 0x43 |
XMODEM的传输过程:

注:实际传输,包序号是从1开始的,文件末尾不够128字节的,用SUB补全。
下边是用tee命令实际抓的标准输出的内容。
管道符“|”把 sx 的标准输出重定向到了 tee 命令的标准输入,tee 命令把内容记录到文件,并发到自己的标准输出,也就是又发回了终端的标准输出。
sx file.txt | tee xmodem.log

补充:
- 使用跳板机登录远程主机,ZMODEM等也是可以使用的,只是有些跳板机比较复杂,有审计功能或其他功能,可能过滤了终端间传输的控制字符,这种情况下就不行了。
- 在终端仿真器screen命令环境中,虽然有个实验性的zmodem模式,但我使用着有些问题,会卡住界面,所以还是退出screen命令再用ZMODEM传输文件吧。
浙公网安备 33010602011771号