通过 SSH 发送文件的代码是什么协议?

通过 SSH 发送文件的代码是什么协议?

我正在阅读一些通过 SSH 客户端发送文件的 Go 代码。

https://github.com/tmc/scp/blob/master/scp.go#L33

它所做的事情之一是scp -t /remote/path.那面旗帜是做什么-t用的?我做了一个man scp,但似乎没有记录。我在本地运行了该命令,它的行为似乎像 cat。

远程运行后scp -t,代码会像这样将字节发送到服务器。

// Some special control header? What is this?
fmt.Fprintf(w, "C%#o %d %s\n", mode, size, fileName)
// Send file bytes.
io.Copy(w, contents)
// Send termination signal?
fmt.Fprint(w, "\x00")

这个协议是什么?它在任何地方都有记录吗?

答案1

AFAIK,除了源代码之外,scp 协议没有记录在其他任何地方scp.c,因此这里尝试概述一下scp工作原理。

当源或目标是远程计算机时,scp将用于ssh连接并启动scp其上的程序:如果复制方向是从远程到本地,则它将启动为scp -f src来自/来源),否则将以scp -t dst(下沉),而本地人scp会采取相反的姿势。

此后,两个 scp 进程在 scp 连接的两端运行,将其用作标准输入/标准输出,并通过其传递文件数据和元数据。

两端都可以使用以下响应来确认消息或发出某些错误情况信号:

  1. "\0": 好的

  2. "\1%s\n", err_msg:非致命错误

  3. "\2%s\n", err_msg: 致命错误

传输开始于到/接收 scp发送一个\0(OK)确认。

然后来自/来源 scp将使用以下消息:

  1. "C%04o %lld %s\n", mode, size, filename:创建一个文件

    接下来是size文件数据字节和 ack ( \0= OK)

  2. "D%04o 0 %.1024s\n", mode, dirname: 目录开始

    递归地跟随C,DT消息,直到

  3. "E\n": 目录结束

  4. "T%llu 0 %llu 0\n", mtime, atime: 文件时间

    如果使用了开关,则在CD消息之前发送该消息。-p

这些消息在进一步处理之前必须得到对方的确认,包括C发送文件数据之前的确认,以及发送文件数据之后发送的确认。

在上面的CD消息中,文件/目录名称中的换行符和其他控制字符(除了\t\x7f)将被转义,例如。\^J,但会不是到达目的地后未逃脱;文字\^J\^M原始名称将保持原样。

致命错误和非致命错误的区别并不一致;任何\1一方都会生成(非致命)错误,但其中一些错误将被视为致命错误,并且scp将在发送或接收错误时退出,让另一方保留这两部分。双方都会因\2(致命)错误或任何意外情况而退出。

与 http 不同,没有规定按块发送文件数据;如果源scp不再能够读取在消息之后开始发送的某些大文件,它将在错误消息/nak之前C发送最多sizeNUL 字节。\1

相关内容