일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Spring
- js
- javabasic
- 자바연습문제
- java기초
- 스프링
- java
- DB
- 자바예제
- 패스트캠퍼스
- String
- ncs
- 패캠챌린지
- 데이터베이스
- 리눅스
- 직장인인강
- 패스트캠퍼스후기
- 자바
- linux
- 재택근무
- 디자인
- 한번에끝내는JavaSpring웹개발마스터초격차패키지Online
- 한번에끝내는JavaSpring웹개발마스터초격차패키지Online강의
- 자바기본
- 웹
- 직장인자기계발
- 디자인패턴
- 자바기초
- 국비
- DesignPattern
- Today
- Total
FIF's 코딩팩토리
자바(java)로 SFTP Client 프로그램 만들기 본문
프로젝트명 - MyProgram
패키지명 - program
클래스명 - MySFTPClient
환경설정
Virtual Box를 통해 CentOS 를 서버로 지정해두고
WindowOS를 클라이언트로 지정 했습니다.
SFTP구현을 위해 오픈소스 라이브러리인 JSch 라이브러리를 사용합니다.
접속하셔서 밑으로 내리다보면 Download컨텐츠에 .jar 파일을 받으시고 이클립스 빌드패스에서 라이브러리에 추가합니다.
SFTP에 접속하기 위해서는 username, 호스트주소(ip주소등), 패스워드가 필요합니다.
스캐너를 이용해 클라이언트 정보를 입력 받아 SFTP서버에 접속하는 방식으로 구현했습니다.
SFTP는 FTP에서 보안을 강화한 프로토콜인데,
JSch 오픈소스 라이브러리를 이용하여 SFTP프로그램을 만들려면 DH알고리즘이 필요합니다.
메인메소드 바로 아래 DH알고리즘을 쓰기위한 코드를 밑과 같이 입력해주시고
http://www.bouncycastle.org/java.html
링크타고 들어가셔서 라이브러리를 다운로드 받으신후 빌드패스에 라이브러리를 추가하시면 됩니다.
구현명령어 : cd pwd get put quit ls rm mkdir chmod chown ln lcd lpwd
package program;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.util.Scanner;
import java.util.Vector;
import javax.crypto.KeyAgreement;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
public class MySFTPClient {
public MySFTPClient() {
}
public static void main(String[] args) {
// DH알고리즘을 쓰기위한 코드
Security.addProvider(new BouncyCastleProvider());
try {
KeyPairGenerator.getInstance("DH");
} catch (NoSuchAlgorithmException e1) {
e1.printStackTrace();
}
try {
KeyAgreement.getInstance("DH");
} catch (NoSuchAlgorithmException e1) {
e1.printStackTrace();
}
Session session = null;
Channel channel = null;
JSch jsch = new JSch();
Scanner scanner = new Scanner(System.in);
System.out.print("계정 입력: ");
String username = scanner.nextLine();
System.out.print("호스트 주소 입력: ");
String host = scanner.nextLine();
System.out.print("비밀번호 입력: ");
String password = scanner.nextLine();
try {
// 세션 객체 생성
session = jsch.getSession(username, host, 22);
// 비밀번호설정
session.setPassword(password);
// 호스트 정보를 검사하지 않음
session.setConfig("StrictHostKeyChecking", "no");
// 세션접속
session.connect();
// sftp채널열기
channel = session.openChannel("sftp");
// 채널접속
channel.connect();
System.out.println("Connected to user@" + host);
} catch (JSchException e) {
e.printStackTrace();
System.out.println("접속에 실패했습니다.");
// 실패시 시스템 종료
System.exit(0);
}
ChannelSftp channelSftp = (ChannelSftp) channel;
while (true) {
System.out.print("sftp> ");
String str = "";
str = scanner.nextLine();
String command = str.split(" ")[0];
if (command.equals("cd")) {
String p1 = str.split(" ")[1];
try {
channelSftp.cd(p1);
} catch (SftpException e) {
System.out.println("Couldn't stat remote file: No such file or directory");
}
} // end cd
else if (command.equals("lcd")) {
// lcd C:\Users\solulink
String p1 = str.split(" ")[1];
try {
channelSftp.lcd(p1);
} catch (SftpException e) {
System.out.println("Couldn't change local directory to " + p1 + ": No such file or directory");
}
} // end lcd
else if (command.equals("pwd")) {
try {
System.out.println("Remote working directory: " + channelSftp.pwd());
} catch (SftpException e) {
e.printStackTrace();
}
} // end pwd
else if (command.equals("lpwd")) {
// lpwd
System.out.println("Local working directory: " + channelSftp.lpwd());
} // end lpwd
else if (command.equals("get")) {
// centos.txt
String p1 = str.split(" ")[1];
// C:\Users\solulink
String p2 = str.split(" ")[2];
try {
channelSftp.get(p1, p2);
} catch (SftpException e) {
System.out.println("Ex)get centos.txt C:\\Users\\solulink");
}
} // end get
else if (command.equals("put")) {
String p1 = str.split(" ")[1];
try {
channelSftp.put(p1);
} catch (SftpException e) {
System.out.println("Ex)put window.txt");
}
} // end put
else if (command.equals("ls") || command.equals("dir")) {
String path = ".";
try {
// 가변길이의 배열
Vector vector = channelSftp.ls(path);
if (vector != null) {
for (int i = 0; i < vector.size(); i++) {
Object obj = vector.elementAt(i);
if (obj instanceof ChannelSftp.LsEntry) {
System.out.println(((ChannelSftp.LsEntry) obj).getLongname());
}
}
}
} catch (SftpException e) {
System.out.println(e.toString());
}
} // end ls
else if (command.equals("rm")) {
try {
String p1 = str.split(" ")[1];
channelSftp.rm(p1);
} catch (SftpException e) {
System.out.println("Couldn't delete file: No such file or directory");
}
} // end rm
else if (command.equals("mkdir")) {
String p1 = str.split(" ")[1];
try {
channelSftp.mkdir(p1);
} catch (SftpException e) {
e.printStackTrace();
}
} // end mkdir
else if (command.equals("rmdir")) {
String p1 = str.split(" ")[1];
try {
channelSftp.rmdir(p1);
} catch (SftpException e) {
System.out.println("Couldn't remove diretory: No such file or directory");
}
} // end rmdir
else if (command.equals("chmod")) {
//접근권한 설정
// chmod 777 window.txt(rwx:7 x:1 wx:3 r-x:5)
String p1 = str.split(" ")[1];
String p2 = str.split(" ")[2];
try {
channelSftp.chmod(Integer.parseInt(p1), p2);
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (SftpException e) {
e.printStackTrace();
}
} // end chmod
else if (command.equals("chown")) {
// 파일소유권변경->일반계정에 root권한 부여(vi /etc/passwd->UID와GID변경)
// 리눅스에서 cat /etc/passwd
// jinpyolee : 1000 sftpuser : 1004
// chown 1000 window.txt
String p1 = str.split(" ")[1];
String p2 = str.split(" ")[2];
try {
channelSftp.chown(Integer.parseInt(p1), p2);
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (SftpException e) {
e.printStackTrace();
}
} // end chown
else if (command.equals("ln") || (command.equals("symlink"))) {
// 링크파일 생성(rwxrwxrwx, 리눅스에서 하늘색으로 나옴)
// ln window.txt win.txt
String p1 = str.split(" ")[1];
String p2 = str.split(" ")[2];
try {
channelSftp.symlink(p1, p2);
} catch (SftpException e) {
e.printStackTrace();
}
} // end ln
else if (command.equals("quit")) {
channelSftp.quit();
// 반복문 나가서 종료
break;
} // end quit
else {
System.out.println("Invalid command.");
}
} // end while
// 연결해제
channelSftp.disconnect();
// 스캐너자원반납
scanner.close();
// 시스템종료
System.exit(0);
}// end main()
}// end class
최대한 CMD창과 비슷하게 구현하도록, 명령어를 띄어쓰기 ( ) 단위로 구분하여 split메소드를 사용해
해당 명령어로 분기하도록 했습니다.
구글에 있는 대부분 sftp프로그램은 하드코딩이여서 실제 사용하는 환경과 최대한 똑같도록 구현해봤습니다.
궁금한점 있으시면 댓글 남겨주세요~
'Back-End > Java(자바)' 카테고리의 다른 글
정적분석 VS 동적분석 (0) | 2019.05.21 |
---|---|
CheckStyle & FindBugs & PMD & ANT (0) | 2019.05.21 |
[Java]어댑터 패턴(Adapter pattern)을 이용한 통합 FTP,SFTP프로그램 (0) | 2019.05.14 |
자바(java)로 만든 FTP와 SFTP Client 통합 프로그램 (2) | 2019.05.09 |
자바(java)로 FTP Client 프로그램 만들기 (1) | 2019.05.08 |