【问题标题】:Explanation for SCP protocol implementation in JSch libraryJSch库中SCP协议实现说明
【发布时间】:2019-09-04 13:11:47
【问题描述】:
我正在考虑使用 JSch 库的示例,可以在此处找到:
http://www.jcraft.com/jsch/examples/ScpFrom.java.html
我无法理解这个示例中的几个代码模式。他们在这里:
是否有任何理由更喜欢 SCP 而不是 SFTP,后者可以使用相同的库运行?
为什么我们在远程主机上运行scp -f <remote file> 而不是简单地运行scp source_file_path destination_file_path?为什么在远程主机上执行更好?
-
在传输的开头有一行
while(true){
int c=checkAck(in);
if(c!='C'){
break;
}
...
这个神奇的C字母是什么意思?为什么C?
-
为什么要一直发送这个信号?
// send '\0'
buf[0]=0; out.write(buf, 0, 1); out.flush();
-
这如何读取文件大小?
long filesize=0L;
while(true){
if(in.read(buf, 0, 1)<0){
// error
break;
}
if(buf[0]==' ')break;
filesize=filesize*10L+(long)(buf[0]-'0'); //What is this??
}
【问题讨论】:
标签:
java
ssh
sftp
scp
jsch
【解决方案1】:
- 是否有任何理由更喜欢 SCP 而不是 SFTP,后者可以使用相同的库运行?
不,SCP 协议已过时。您现在应该始终使用 SFTP。
尽管 SFTP 协议的简单实现往往比 SCP 传输更慢(由于其数据包性质,有效地实现 SFTP 传输并不容易)。
- 为什么我们在远程主机上运行
scp -f <remote file> 而不是简单地运行scp source_file_path destination_file_path?为什么在远程主机上执行更好?
这就是 SCP 协议的工作原理。 OpenSSH scp 二进制文件既可以用作服务器,也可以用作客户端。因此,当您在本地运行 scp 时,它会通过 SSH 连接并在服务器上运行 scp。然后两个实例相互通信。 JSch 替换了scp 的本地实例。但它仍然需要远程实例来完成传输。
如果您在本地运行 scp,则必须在计算机上安装 OpenSSH。在 Unix 上可能很常见,但在 Windows 上绝对不是。此外,也没有简单/标准化的方法来捕获来自scp 程序的结果,将它们转换为 JSch Java 接口。这与 JSch(或任何其他 SFTP 库)自己实现 SFTP 协议而不是使用 sftp 程序的原因相同。
- 这个神奇的C字母是什么意思?为什么选择 C?
SCP 协议的每个命令都由一个字符标识。 C代表“文件传输”,D代表“目录传输”,文件传输前的T表示下一个传输文件的修改时间等等。不知道为什么是C而不是例如F。
- 为什么要一直发送这个信号?
NULL (\0) 字符命令是确认/响应其他站点接收到的命令已完成。
- 这如何读取文件大小?
C 命令具有语法(它是人类可读的字符串):
C permissions size filename
例如:
C 0644 153634 index.php
代码中的循环将字符串 "153634" 转换为数字 153634。它看起来有点过于复杂的实现,但它确实有效。
另见How is SCP (secure copy protocol) file transfer working?