본문 바로가기
블로그 이미지

방문해 주셔서 감사합니다! 항상 행복하세요!

  
   - 문의사항은 메일 또는 댓글로 언제든 연락주세요.
   - "해줘","답 내놔" 같은 질문은 답변드리지 않습니다.
   - 메일주소 : lts06069@naver.com


Java(자바)

jsch 사용법(ssh 연결)

야근없는 행복한 삶을 위해 ~
by 마샤와 곰 2019. 4. 25.

 

 

자바에서 ssh를 활용해서 다른 서버로 접속하여 명령어를 실행해야 되는 경우가 있었다.

이럴때는 jsch를 활용하면 쉽게 사용이 가능하다.

 

Jsch를 활용한 개념은 3단계로 이루어 진다.

1. Jsch 클래스를 생성한다.

2. ssh를 통해서 연결한다.

3. 원하는 행위를 연결한 서버로 전송한다.

 

간단하게 먼저 연결하는 예제를 살펴보자.

import java.io.InputStream;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import com.jcraft.jsch.SftpProgressMonitor;

public class SFTPSender {
    public static void connect() throws Exception{
        JSch jsch = new JSch();
        Session session = jsch.getSession(접속아이디, 주소, 포트);
        session.setPassword(비밀번호);
        java.util.Properties config = new java.util.Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        session.connect();  //연결 시도
        System.out.println(session);
        session.disconnect();
    }
}

 

간단하게 연결하는 코드이다.

저렇게 연결한 뒤에 세션에서 채널을 선택하고, 선택된 채널에서 무엇을 할 지 정하면 된다.

 

그러면 명령어를 전송하는 코드를 만들어보자.

import java.io.InputStream;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import com.jcraft.jsch.SftpProgressMonitor;

public class SFTPSender {
    public static void order() throws Exception{
        JSch jsch = new JSch();
        Session session = jsch.getSession(접속아이디, 주소, 포트);
        session.setPassword(비밀번호);
        java.util.Properties config = new java.util.Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        session.connect();  //연결
        
        
        Channel channel = session.openChannel("exec");  //채널접속
        ChannelExec channelExec = (ChannelExec) channel; //명령 전송 채널사용
        channelExec.setPty(true);
        channelExec.setCommand("netstat -tnlp"); //내가 실행시킬 명령어를 입력
        
        
        //콜백을 받을 준비.
        StringBuilder outputBuffer = new StringBuilder();
        InputStream in = channel.getInputStream();
        ((ChannelExec) channel).setErrStream(System.err);        
        
        channel.connect();  //실행
        
  
        byte[] tmp = new byte[1024];
        while (true) {
            while (in.available() > 0) {
                int i = in.read(tmp, 0, 1024);
                outputBuffer.append(new String(tmp, 0, i));
                if (i < 0) break;
            }
            if (channel.isClosed()) {
                System.out.println("결과");
                System.out.println(outputBuffer.toString());
                channel.disconnect();
            }
        }        
    }
}

 

채널을 오픈할 때 exec를 매개변수로 하여서 생성하였다.

그리고서는 명령을 connect 메소드를 통해서 실행하였다.

그러면 파일을 받는 것은 어떻게 할까?

해당 채널을 오픈할 때의 내용을 변경하여주면 가능하다.

import java.io.*;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import com.jcraft.jsch.SftpProgressMonitor;

public class SFTPSender {

    public static void download() throws Exception{
        JSch jsch = new JSch();
        Session session = jsch.getSession(접속아이디, 주소, 포트);
        session.setPassword(비밀번호);
        java.util.Properties config = new java.util.Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        session.connect();  //연결 시도       
        
        ChannelSftp channelSftp = null;
        InputStream in = null;
        Channel channel = null;
        try{ 
            channel = session.openChannel("sftp"); //방식설정
            channel.connect();
            channelSftp = (ChannelSftp) channel;
            channelSftp.cd("파일을받을디렉토리");  //해당 디렉토리 이동
            in = channelSftp.get("파일명");  //파일을 받는다.
        }catch (Exception e) {
			e.printStackTrace();
        }        
        channel.disconnect();   
    }
}

 

명령을 전달한 뒤에 내용을 받는 구간이 없어서 그런지 코드가 더 훨씬 깔끔하다.

cd라는 메소드를 통해서 파을을 받을 곳으로 이동한 뒤에 get메소드를 호출해서 쉽게 가능 하다.

그렇다면 위 코드를 조금만 수정하면 파일 보내는 것도 가능 하다.

import java.io.*;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import com.jcraft.jsch.SftpProgressMonitor;

public class SFTPSender {

    public static void download() throws Exception{
        JSch jsch = new JSch();
        Session session = jsch.getSession(접속아이디, 주소, 포트);
        session.setPassword(비밀번호);
        java.util.Properties config = new java.util.Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        session.connect();  //연결 시도       
        
        ChannelSftp channelSftp = null;
        InputStream in = null;
        Channel channel = null;
        try{ 
            channel = session.openChannel("sftp"); //방식설정
            channel.connect();
            channelSftp = (ChannelSftp) channel;
            
            //put을 통해서 파일을 보낸다. 
            //SftpProgressMonitor 인터페이스를 굳이 사용하지 않아도 된다!!
            channelSftp.put("전송할디렉토리+파일명칭", "받을디렉토리+파일명칭", new SftpProgressMonitor() {
                private long max = 0;
                private long count = 0;
                private long percent = 0;
                @Override
                public void init(int op, String src, String dest, long max) {
                    this.max = max;
                }
                @Override
                public void end() {
		
                }
                @Override
                public boolean count(long bytes) {
                    this.count += bytes;
                    long percentNow = this.count*100/max;
                    if(percentNow>this.percent){
                        this.percent = percentNow;
                        System.out.println("progress : " + this.percent); // 프로그래스
                    }
            		return true;  //false인경우 count 메소드가 동작하지 않는다.
                }
            });            
        }catch (Exception e) {
			e.printStackTrace();
        }        
        channel.disconnect();   
    }
}

 

파일을 전송하는 것도 put이라는 메소드를 통해서 쉽게 가능하다.

눈여겨 보아야할 점이 SftpSftpProgressMonitor 인터페이스를 통해서 콜백행위를 알 수 있게 해준다는 점 이다.

시작, 종료, 프로그래스 관련된 내용이 확인 가능 하다.

 

 

라이브러리 추가는 maven과 gradle 둘 다 가능하다.

* maven

<!-- https://mvnrepository.com/artifact/com.jcraft/jsch -->
<dependency>
    <groupId>com.jcraft</groupId>
    <artifactId>jsch</artifactId>
    <version>0.1.55</version>
</dependency>

* gradle

// https://mvnrepository.com/artifact/com.jcraft/jsch
compile group: 'com.jcraft', name: 'jsch', version: '0.1.55'

 

maven 리파지토리를 방문해서 원하는 버전과 스펙을 확인하자!

 

아니면 검색하면 해당 홈페이지에서도 받을 수 있다.

http://www.jcraft.com/jsch/

 

JSch - Java Secure Channel

JSch - Java Secure Channel JSch is a pure Java implementation of SSH2. JSch allows you to connect to an sshd server and use port forwarding, X11 forwarding, file transfer, etc., and you can integrate its functionality into your own Java programs. JSch is l

www.jcraft.com

* 추가

- 윈도우 서버에서는 ssh관련된 접속이 잘(매우) 안된다..

- 요 2가지 방식, 리눅스 -> 리눅스, 윈도우 -> 리눅스 는 잘 되는데 목적지가 윈도우면 정말 잘 안된다.

 

 

반응형
* 위 에니메이션은 Html의 캔버스(canvas)기반으로 동작하는 기능 입니다. Html 캔버스 튜토리얼 도 한번 살펴보세요~ :)
* 직접 만든 Html 캔버스 애니메이션 도 한번 살펴보세요~ :)

댓글