Linux

在程式碼中通過 SSH 發送文件的協議是什麼?

  • March 5, 2020

我正在閱讀一些通過 SSH 客戶端發送文件的 Go 程式碼。

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

它所做的其中一件事是scp -t /remote/path. 那面-t旗幟是乾什麼用的?我做了一個man scp,但似乎沒有記錄。我在本地執行命令,它的行為似乎像貓。

遠端執行後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")

這個協議是什麼?它在任何地方都有記錄嗎?

AFAIK,除了 scp 的原始碼之外,其他任何地方都沒有記錄 scp 協議scp.c,因此這裡嘗試概述其scp工作原理。

當源或目標是遠端機器時,scp將用於ssh連接並scp在其上啟動程序:如果複製方向是從遠端到本地,則啟動為scp -f srcfrom / source),否則為以scp -t dst( to / sink ) 開頭,本地scp將採取相反的姿勢。

此後,兩個 scp 程序在 scp 連接的兩端執行,將其用作它們的標準輸入/標準輸出,並通過它傳遞文件數據和元數據。

兩端都可以使用以下響應來確認消息或發出某些錯誤情況的信號:

  1. "\0": 好的
  2. "\1%s\n", err_msg: 非致命錯誤
  3. "\2%s\n", err_msg: 致命錯誤

傳輸由to / sink scp發送\0(OK)確認開始。

然後from / source 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: 文件時間

如果使用了開關,則在CorD消息之前發送。-p

這些消息在進一步處理之前必須得到對方的確認,包括C在發送文件數據之前和之後發送的確認。

在上面的CandD消息中,文件/目錄名稱中的換行符和其他控製字元(\t和除外\x7f)將被轉義為例如。\^J,但不會在目的地逃脫;文字\^J\^M原始名稱將保持原樣。

致命錯誤和非致命錯誤的區別並不一致;任何一方都只會\1產生(非致命的)錯誤,但其中一些會被認為是致命的,並且scp會在發送或接收它們時退出,讓另一方持有兩個部分。雙方將在\2(致命)錯誤或任何意外情況下退出。

與 http 不同,沒有分塊發送文件數據的規定;如果源scp不再能夠讀取它在消息之後開始發送的一些大文件,它將在錯誤消息/nak之前C發送最多其sizeNUL 字節。\1

引用自:https://unix.stackexchange.com/questions/539423