通过ssh协议下载和上传文件

1、使用ssh的好处

通过使用SSH,你可以把所有传输的数据进行加密,这样"中间人"这种攻击方式就不可能实现了,而且也能够防止DNS欺骗和IP欺骗。使用SSH,还有一个额外的好处就是传输的数据是经过压缩的,所以可以加快传输的速度。
所谓“中间人”的攻击方式, 就是“中间人”冒充真正的服务器接收你传给服务器的数据,然后再冒充你把数据传给真正的服务器。服务器和你之间的数据传送被“中间人”一转手做了手脚之后,就会出现很严重的问题。

2、上传和下载要解决的两个问题:

  • 上传(下载)的实现过程
  • 在上传(下载)的过程中,前端需要知道上传的进度,更新进度条;在上传(下载)结束后,前端需要知道上传已经结束,更新上传数量

3、上传(下载)过程:

1)上传前的操作

在上传之前,我们要获取这几个参数:

  • 被上传的文件在本地电脑的存储路径(绝对路径,包含文件名及后缀);
  • 要上传的目的地的路径(远程端的路径,包含文件名及后缀),存到哪里;
  • 一个用于上传的server对象,其中包括ip、port、username、password

2)调用服务端上传方法

在前端调用 Meteor.call,通知服务端相应的上传方法,并把上述参数传给服务端,去做上传

3)服务端执行上传(下载)

1、实现上传(下载)我们需要借助一个依赖包ssh2-sftp-client。
所以先下载它。

npm install ssh2-sftp-client

2、引入

let sftpClient = require('ssh2-sftp-client');

3、创建一个sftp对象

let sftp = new sftpClient();

4、上传的过程

sftp.connect({
  host: '127.0.0.1',
  port: '8080',
  username: 'username',
  password: '******'
}).then(() => {
    return sftp.fastPut(localPath,remotePath, {step: (total_transferred, chunk, total) => {
      //每小段上传完成后的回调
    }})
    })
    .then(data => {
  console.log( '上传结束',data);
  sftp.end();
}).catch(err => {
  console.log('上传出现错误',err);
  sftp.end();
});
  • 1)建立ssh连接,调用sftp.connect(server)方法,并传入server对象
  • 2)执行上传,sftp.connect()返回一个Promise对象,在第一个then中,调用sftp.fastPut执行上传文件的操作
    fastPut方法只是其中的一种上传方法,ssh包还提供有其它的上传方法。
fastPut(destFile, srcFile, options) ==> string

fastPut方法共有三个参数

  • destFile为远程文件的路径(尾)
  • srcFile为本地的路径(源)
  • options为配置对象
    options共有四个属性,其中step属性的值是一个方法。文件上传操作并不是一次性完成的,而是将一个大文件分成一小块一小块上传,所以每一小块上传完成后就调用一次这个方法。

在上传过程中会多次调用这个step方法。
step方法共有三个参数
- total_transferred,已经上传了多少k(包含本次上传的)
- chunk,本次上传了多少k
- total,此文件一共有多少k

存在的bug
上传过程中多次调用的step方法,其参数total_transferred,有时并不是按照递增执行的,
例如:按照正常情况,total_transferred的值应该是这样:…0.7,0.8,0.9,1
但有时它会是这样:…0.7,1,0.8,0.9,不靠谱。

  • 3)当全部上传完成后,就执行第二个then中的回调方法。
  • 回调的参数data是一个字符串,告诉你上传的结果,文件从哪上传到哪成功了。例如‘ E:\work\sg2148_MPanelCtl\img\Diagonal-45FoV-left.bmp was successfully uploaded to /opt/seeing/app/rgb_config/images/Diagonal-45FoV-left.bmp!’
    在里面调用end方法,结束ssh
  • 4)当catch到error时也end结束ssh。

5、下载的过程
下载的过程同上传的过程类似

  let sftp = new sftpClient();
  sftp.connect(server).then(() => {
    return sftp.fastGet(srcFile, destFile,{step: (total_transferred, chunk, total,) => {
     //每小段下载完成后的回调
    }});
    }).then(() =>{
      console.log("下载结束");
      sftp.end();
    }).catch((err) => {
      console.log('下载出现错误',err);
      sftp.end();
  });

下载使用的是sftp.fastGet方法,并且其参数的顺序与上传不同
第一个参数是远程的路径(源)
第二个参数是本地的路径(尾)
总之无论上传还是下载方法,其第一个参数都是从哪里的地址,第二个参数是到哪里的地址。

4、前端如何知道每个文件上传的进度

上传一个文件是分多块上传的,每上传一小块就调用一次step函数。并且step函数的参数中含有已经上传完成的体积大小。

1、第一种方法,前端轮询数据库

在服务端每次调用step函数时,都将上传的进度更新到数据库;然后在前端向数据库轮询,当上传完成时resolve出去。
但我在项目中发现,服务端更新数据库有时会存在bug,数据更新不上,即使改成递归的更新数据库(即更新数据库不成功,就再次更新,直到更新成功为之),但还是偶尔有问题。
轮询函数

  • 查询一次数据库获取传输情况的数据
  • 没查到递归调用
  • 根据状态做不同操作
  • 如果还是正在传输,那么递归调用
  async sftpSchedule(server, src, dest, successCb, failCb) {
    let sftpInfo = await CommonMethods.meteorCall(
      "querySftpInfo",
      server,
      src,
      dest
    );
    let status = sftpInfo.status;
    if (status === 1) {//传输完成
      successCb();
    } else if (status === -1) {//传输失败
      failCb();
    } else if (status === 0) {//传输正在进行
      let percentComplete =
      sftpInfo.total > 0 ? sftpInfo.total_transferred / sftpInfo.total : 0;
      let progress = parseInt(percentComplete * 100);//进度
      setTimeout(() => {
        this.sftpSchedule(server, src, dest, successCb, failCb);
      }, 500);
    } else {
      setTimeout(() => {
        this.sftpSchedule(server, src, dest, successCb, failCb);
      }, 500);
    }
  }

2、第二种,使用socket通知

服务端在step函数中向前端发消息,在传输完成时向前端发消息,在传输遇到错误时向前端发消息;前端根据这些消息做相应的处理。具体操作已在另一篇文章详述。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在进行SSH升级9.03上传文件的过程中,我们需要遵循以下步骤: 首先,确保SSH服务已经安装在目标主机上。如果没有安装,需要先进行安装。可以通过运行适合操作系统的包管理器来安装SSH服务。 接下来,需要查看并确认目标主机的SSH版本是否为9.03。可以通过在命令行中输入以下命令来检查SSH版本: ``` ssh -V ``` 如果当前SSH版本不是9.03,需要进行升级。可以通过访问SSH官方网站或者相关的软件仓库来下载最新版本的SSH软件包,并按照官方提供的安装指南进行升级。 一旦SSH服务以及升级为9.03版本,我们可以开始上传文件。可以使用以下命令进行文件传输: ``` scp /本地文件路径 用户名@服务器地址:/目标文件路径 ``` 在这个命令中,我们需要将`/本地文件路径`替换为本地计算机上要上传的文件的路径,`用户名`替换为远程服务器的用户名,`服务器地址`替换为远程服务器的IP地址或域名,`/目标文件路径`替换为文件在远程服务器上的存储路径。 输入以上命令后,系统可能会提示你输入远程服务器的密码或者SSH密钥密码。根据实际情况输入密码,然后等待文件传输完成。 通过按照上述步骤,我们可以在进行SSH升级为9.03版本后成功上传文件。 ### 回答2: SSH是一种网络协议,用于在网络上安全地远程登录和执行命令。针对升级SSH到9.03版本并上传文件的问题,需要分两部分进行回答。 首先是升级SSH到9.03版本的步骤。要将SSH升级到9.03版本,可按照以下步骤进行操作: 1. 在服务器上打开终端(或者远程登录到服务器)。 2. 确认当前SSH版本,可以使用以下命令:`ssh -V`。系统将显示当前SSH版本号。 3. 下载SSH 9.03的安装包。可以通过SSH的官方网站或其他可信渠道获取安装包。 4. 解压安装包,并进入相应的目录。 5. 使用终端运行如下命令开始安装:`./configure`。这将检查系统配置并准备安装。 6. 如果配置成功,则运行`make`命令开始编译。 7. 编译完成后,运行`make install`命令进行安装。 8. 等待安装完成,这可能需要一些时间。 9. 安装完成后,可以使用`ssh -V`命令再次确认SSH版本是否升级到了9.03。 完成了SSH升级之后,可以使用以下步骤进行文件上传: 1. 打开终端(或者远程登录到服务器)。 2. 使用以下命令连接到远程服务器:`ssh 用户名@服务器IP地址`。需要将"用户名"替换为实际的用户名,"服务器IP地址"替换为实际的服务器IP地址。 3. 当连接成功后,使用`cd`命令切换到想要上传的目录。 4. 通过以下命令上传文件:`scp 本地文件路径 服务器用户名@服务器IP地址:服务器目标路径`。其中"本地文件路径"是要上传的文件在本地计算机上的路径,"服务器用户名"是服务器上的有效用户名,"服务器IP地址"是目标服务器的IP地址,"服务器目标路径"是要将文件上传到的目标路径。 5. 等待上传完成,上传进度将会显示在终端上。 6. 上传完成后,可以使用`ls`命令查看目标路径,确认文件已经成功上传到服务器。 以上就是将SSH升级到9.03版本并上传文件的过程,希望对你有帮助。 ### 回答3: 要升级SSH(Secure Shell)并上传文件到9.03版本,首先需要确保已经安装了SSH客户端和服务器软件,并且能够成功连接到服务器。以下是一个简单的步骤指南: 1. 检查当前SSH版本:在终端中输入命令“ssh -V”,确认当前SSH版本。如果版本低于9.03,则需要进行升级。 2. 下载最新的SSH版本:在SSH官方网站或信任的软件下载网站上找到最新的SSH版本,下载相关软件包。 3. 安装新的SSH版本:解压下载的软件包,并按照提供的安装指南进行安装。具体的安装步骤可能因操作系统的不同而有所差异。 4. 配置SSH服务器:在终端中打开SSH服务器配置文件,通常位于'/etc/ssh/sshd_config'。编辑该文件以确保SSH服务器的正确配置。例如,可以配置允许文件上传的目录和权限。 5. 启动SSH服务器:保存并关闭配置文件后,在终端中输入命令“sudo service ssh restart”(具体命令可能因操作系统的不同而有所差异),以重新启动SSH服务器。 6. 连接到服务器:使用SSH客户端连接到服务器。可以使用命令“ssh <服务器IP地址>”或使用图形化的SSH客户端工具。 7. 上传文件:在SSH会话中,使用SCP(Secure Copy)命令向服务器上传文件。使用命令“scp <本地文件路径> <目标服务器用户名@服务器IP地址:目标路径>”来上传文件。 8. 验证文件上传:上传完成后,检查服务器上目标路径是否出现了新上传的文件。可以使用命令“ls <目标路径>”来验证。 通过按照上述步骤,您将能够升级SSH到9.03版本并成功上传文件。请注意,具体步骤可能因操作系统和SSH软件版本的不同而有所变化,建议在执行操作前参考相关的文档和教程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值