# 使用scp从windows拷贝文件到linux服务器 scp(security copy protocol)

使用scp从windows拷贝文件到linux服务器 scp(security copy protocol)

1. 问题缘起:

需求:公司的项目系统需要将硬件采集到window上的数据文件转移到我们的linux服务器上指定文件夹

2. 寻找解决方案: >

开始时没有搞清楚需求,以为就是像web系统一样通过表单上传文件到服务器一样(只是不需要表单了,有点傻呵呵),想到的都是javaweb的文件上传工具、方法,显然是不行的,搞了2个小时左右,没有找到一个行的通的解决方案,还在继续郁闷摸索,当然摸索的过程中也不断的明确了点我到底想要什么 1、所要做的操作是拷贝文件,2、环境是跨系统的,远程的,3、操作的工具语言是java; 差不多在这个时候,我觉得为了工程的进度不能在自己一个这样胡乱摸索了,太浪费时间,老大就在旁边,何不求教!

然后向老大描述了我的思考和探索进展情况,说还没有找到可行的解决方案。老大就是老大,果然经验(知识面广)很重要,听了以后告诉我scp,让我看看,还帮我找了一个博客。看到scp,然后再思考对比发现,正是我要找的方案。至此,找到了理论上可以的解决方案。果然要多听老人言,哈哈。

反思

那如果没有老大的指点,我们应该如何面对一个问题?这个是关键。从这次问题中我觉得可以得到几点答案:
> 1、就是知道想要什么效果? 2、现在的是什么情况? 3、想要怎么做、可以怎么做?
说白了就是搞清需求,在有针对性的找解决方案。

关键代码

package service;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.SCPClient;

public class Scpclient {

    static private Scpclient instance;

    static synchronized public Scpclient getInstance(String IP, int port,
            String username, String passward) {
        if (instance == null) {
            instance = new Scpclient(IP, port, username, passward);
        }
        return instance;
    }

    public Scpclient(String IP, int port, String username, String passward) {
        this.ip = IP;
        this.port = port;
        this.username = username;
        this.password = passward;
    }


    public void getFile(String remoteFile, String localTargetDirectory) {
        Connection conn = new Connection(ip,port);
        try {
            conn.connect();
            boolean isAuthenticated = conn.authenticateWithPassword(username,
                    password);
            if (isAuthenticated == false) {
                System.err.println("authentication failed");
            }
            SCPClient client = new SCPClient(conn);
            client.get(remoteFile, localTargetDirectory);
            conn.close();
        } catch (IOException ex) {
            Logger.getLogger(SCPClient.class.getName()).log(Level.SEVERE, null,ex);
        }
    }


    public void putFile(String localFile, String remoteTargetDirectory) {
        Connection conn = new Connection(ip,port);
        try {
            conn.connect();
            boolean isAuthenticated = conn.authenticateWithPassword(username,
                    password);
            if (isAuthenticated == false) {
                System.err.println("authentication failed");
            }
            SCPClient client = new SCPClient(conn);
            client.put(localFile, remoteTargetDirectory);
            conn.close();
        } catch (IOException ex) {
            Logger.getLogger(SCPClient.class.getName()).log(Level.SEVERE, null,ex);
        }
    }


    public void  putFile(String localFile, String remoteFileName,String remoteTargetDirectory,String mode) {
        Connection conn = new Connection(ip,port);
        try {
            conn.connect();
            boolean isAuthenticated = conn.authenticateWithPassword(username,
                    password);
            if (isAuthenticated == false) {
                System.err.println("authentication failed");
            }
            SCPClient client = new SCPClient(conn);
            if((mode == null) || (mode.length() == 0)){
                mode = "0600";
            }
            client.put(localFile, remoteFileName, remoteTargetDirectory, mode);

            //重命名
            ch.ethz.ssh2.Session sess = conn.openSession();
            String tmpPathName = remoteTargetDirectory +File.separator+ remoteFileName;
            String newPathName = tmpPathName.substring(0, tmpPathName.lastIndexOf("."));
            sess.execCommand("mv " + remoteFileName + " " + newPathName);//重命名回来

            conn.close();
        } catch (IOException ex) {
            Logger.getLogger(SCPClient.class.getName()).log(Level.SEVERE, null,ex);
        }
    }

    public void putFile(String localFile, String remoteFileName,String remoteTargetDirectory) {
        Connection conn = new Connection(ip,port);
        try {
            conn.connect();
            boolean isAuthenticated = conn.authenticateWithPassword(username,
                    password);
            if (isAuthenticated == false) {
                System.err.println("authentication failed");
            }
            SCPClient client = new SCPClient(conn);
            client.put(getBytes(localFile), remoteFileName, remoteTargetDirectory);
            conn.close();
        } catch (IOException ex) {
            Logger.getLogger(SCPClient.class.getName()).log(Level.SEVERE, null,ex);
        }
    }

    public static byte[] getBytes(String filePath) {
        byte[] buffer = null;
        try {
            File file = new File(filePath);
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream byteArray = new ByteArrayOutputStream(1024*1024);
            byte[] b = new byte[1024*1024];
            int i;
            while ((i = fis.read(b)) != -1) {
                byteArray.write(b, 0, i);
            }
            fis.close();
            byteArray.close();
            buffer = byteArray.toByteArray();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buffer;
    }

    private String ip;
    private int port;
    private String username;
    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

}

3. 调试尝试解决方案核心功能

> 首先在网上找到的解决方案,刚好有代码,就直接拿来用上了,需要一个scp支持jar包

—— [anymed-ssh2-build210 jar

包]

调试遇到问题1:

报错:unknown host exception 未知主机异常

后来发现是把ip写错了,ip比如192.168.0.1,被我写成了http://192.168.0.1,肯定就找不到主机了,改回来就好了

调试遇到问题2:

报错:Remote scp terminated unexpectedly
意思:远程scp意外终止。
刚开始只是盲目的去网上找这个错误的相关信息,然而结果并不理想,但是随着对scp的了解,发现原来scp也是linux上运行的一个命令协议,和ssh一样,那就现在linux上以scp协议连接然后 直接使用scp命令试一下吧,试一下,果然出错了,如下:

[root@fengyun scpclient]# scp -t -d /home/scpclient/
-bash: scp: command not found

因为远程liunx服务器端不能运行scp命令,果然在网上找打解决办法:
使用yum install openssh-clients命令安装openssh-clients
“`
[root@fengyun tmp]# yum install openssh-clients
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.zju.edu.cn
* extras: mirrors.163.com
* updates: mirrors.163.com
base | 3.7 kB 00:00
extras | 3.4 kB 00:00
updates | 3.4 kB 00:00
Setting up Install Process
Resolving Dependencies
–> Running transaction check
—> Package openssh-clients.x86_64 0:5.3p1-122.el6 will be installed
–> Processing Dependency: openssh = 5.3p1-122.el6 for package: openssh-clients-5.3p1-122.el6.x86_64
–> Processing Dependency: libedit.so.0()(64bit) for package: openssh-clients-5.3p1-122.el6.x86_64
–> Running transaction check
—> Package libedit.x86_64 0:2.11-4.20080712cvs.1.el6 will be installed
—> Package openssh.x86_64 0:5.3p1-94.el6 will be updated
–> Processing Dependency: openssh = 5.3p1-94.el6 for package: openssh-server-5.3p1-94.el6.x86_64
—> Package openssh.x86_64 0:5.3p1-122.el6 will be an update
–> Running transaction check
—> Package openssh-server.x86_64 0:5.3p1-94.el6 will be updated
—> Package openssh-server.x86_64 0:5.3p1-122.el6 will be an update
–> Finished Dependency Resolution

Dependencies Resolved

==================================================================================================================================================================================================================

Package Arch Version Repository Size

Installing:
openssh-clients x86_64 5.3p1-122.el6 base 443 k
Installing for dependencies:
libedit x86_64 2.11-4.20080712cvs.1.el6 base 74 k
Updating for dependencies:
openssh x86_64 5.3p1-122.el6 base 277 k
openssh-server x86_64 5.3p1-122.el6 base 329 k

Transaction Summary

Install 2 Package(s)
Upgrade 2 Package(s)

Total download size: 1.1 M
Is this ok [y/N]: y
Downloading Packages:
(1/4): libedit-2.11-4.20080712cvs.1.el6.x86_64.rpm | 74 kB 00:00
(2/4): openssh-5.3p1-122.el6.x86_64.rpm | 277 kB 00:02
(3/4): openssh-clients-5.3p1-122.el6.x86_64.rpm | 443 kB 00:03

(4/4): openssh-server-5.3p1-122.el6.x86_64.rpm | 329 kB 00:02

Total 147 kB/s | 1.1 MB 00:07
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
Updating : openssh-5.3p1-122.el6.x86_64 1/6
Installing : libedit-2.11-4.20080712cvs.1.el6.x86_64 2/6
Installing : openssh-clients-5.3p1-122.el6.x86_64 3/6
Updating : openssh-server-5.3p1-122.el6.x86_64 4/6
Cleanup : openssh-server-5.3p1-94.el6.x86_64 5/6
Cleanup : openssh-5.3p1-94.el6.x86_64 6/6
Verifying : openssh-server-5.3p1-122.el6.x86_64 1/6
Verifying : libedit-2.11-4.20080712cvs.1.el6.x86_64 2/6
Verifying : openssh-5.3p1-122.el6.x86_64 3/6
Verifying : openssh-clients-5.3p1-122.el6.x86_64 4/6
Verifying : openssh-5.3p1-94.el6.x86_64 5/6
Verifying : openssh-server-5.3p1-94.el6.x86_64 6/6

Installed:
openssh-clients.x86_64 0:5.3p1-122.el6

Dependency Installed:
libedit.x86_64 0:2.11-4.20080712cvs.1.el6

Dependency Updated:
openssh.x86_64 0:5.3p1-122.el6 openssh-server.x86_64 0:5.3p1-122.el6

Complete!
[root@fengyun tmp]#

“`

测试代码:


@Test
public void test(){
Scpclient scpclient = new Scpclient("192.168.0.122", 22, "root", "linux root账户密码");
scpclient.putFile("C:\\Users\\zhengss\\Pictures\\fullinfo.png", "fullinfo.png", "/home/scpclient/", null);
}

再使用secureCRT远程连接linux工具,选择scp协议连接linux服务器,测试scp -t -d /home/scpclient/
如下

再次使用java程序传输文件成功,欧耶!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值