개발자의 끄적끄적

[java] 자바(java)로 만든 FTP와 SFTP Client 통합 프로그램 [펌] 본문

개발/java & jsp

[java] 자바(java)로 만든 FTP와 SFTP Client 통합 프로그램 [펌]

효벨 2020. 2. 28. 03:00
728x90
반응형

[java] 자바(java)로 만든 FTP와 SFTP Client 통합 프로그램 [펌]

 

아래에는 FTP, SFTP 따로 동작하는 프로그램인데

클래스를 크게 3개로 나누어서 통합프로그램을 만들었습니다.

 

서버로 설정한 CentOS

Virtual Box를 사용하여 CentOS를 임의의 서버로 설정하였습니다.

 

프로젝트 구조

프로젝트 구조는 위 사진과 같습니다.

 

FTP와 SFTP를 사용하기 위해선 commons.net과 JSch라이브러리가 필요한데 이와 관련된 내용은 아래글에 있고,

 

여기선 통합프로그램을 어떻게 구현했는지에 대한 코드만 올리겠습니다.

 

ProgramStart.java

  1. package program;
  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.io.InputStreamReader;
  5. public class ProgramStart {
  6. public static void main(String[] args) {// 메인 메소드
  7. String command = "";
  8. BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  9. MyFTPClient myFTPClient = new MyFTPClient();
  10. MySFTPClient mySFTPClinet = new MySFTPClient();
  11. System.out.print("프로토콜 유형: ");
  12. try {
  13. command = br.readLine();
  14. if (command.equals("ftp") || command.equals("FTP")) {
  15. myFTPClient.start();
  16. } else if (command.equals("sftp") || command.equals("SFTP")) {
  17. mySFTPClinet.start();
  18. } else {
  19. System.out.println("어떤 프로토콜을 쓸건지 다시 입력해주세요.");
  20. System.exit(0);
  21. }
  22. } catch (IOException e) {
  23. e.printStackTrace();
  24. }
  25. }
  26. }

 

MyFTPClient.java

  1. package program;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.FileNotFoundException;
  5. import java.io.FileOutputStream;
  6. import java.io.IOException;
  7. import java.io.InputStream;
  8. import java.io.OutputStream;
  9. import java.util.Scanner;
  10. import org.apache.commons.net.ftp.FTP;
  11. import org.apache.commons.net.ftp.FTPClient;
  12. import org.apache.commons.net.ftp.FTPFile;
  13. import org.apache.commons.net.ftp.FTPReply;
  14. public class MyFTPClient {
  15. public void start() {
  16. FTPClient ftpClient = new FTPClient();
  17. // 서버접속
  18. Scanner scanner = new Scanner(System.in);
  19. System.out.print("호스트 주소 입력: ");
  20. String server = scanner.nextLine();
  21. try {
  22. ftpClient.connect(server, 21);
  23. if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
  24. System.out.println(server + "에 연결됐습니다.");
  25. System.out.println(ftpClient.getReplyCode() + " SUCCESS CONNECTION.");
  26. }
  27. } catch (Exception e) {
  28. System.out.println("서버 연결 실패");
  29. System.exit(0);
  30. }
  31. // 계정입력
  32. System.out.print("계정 입력: ");
  33. String user = scanner.nextLine();
  34. System.out.print("비밀번호 입력: ");
  35. String password = scanner.nextLine();
  36. try {
  37. ftpClient.login(user, password);
  38. System.out.println(ftpClient.getReplyCode() + " Login successful.");
  39. } catch (IOException e) {
  40. System.out.println(ftpClient.getReplyCode() + " Login incorrect.");
  41. System.exit(0);
  42. }
  43. // 명령어시작
  44. while (true) {
  45. System.out.print("ftp> ");
  46. String str = "";
  47. str = scanner.nextLine();
  48. String[] params = str.split(" ");
  49. String command = params[0];
  50. // 명령어 시작
  51. if (command.equals("cd")) {
  52. String path = params[1];
  53. try {
  54. ftpClient.changeWorkingDirectory(path);
  55. } catch (IOException e) {
  56. e.printStackTrace();
  57. }
  58. } // end cd
  59. else if (command.equals("mkdir")) {
  60. String directory = params[1];
  61. try {
  62. ftpClient.makeDirectory(directory);
  63. } catch (IOException e) {
  64. e.printStackTrace();
  65. }
  66. } // end mkdir
  67. else if (command.equals("rmdir")) {
  68. String directory = params[1];
  69. try {
  70. ftpClient.removeDirectory(directory);
  71. } catch (IOException e) {
  72. e.printStackTrace();
  73. }
  74. } // end rmdir
  75. else if (command.equals("binary")) {
  76. try {
  77. ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
  78. System.out.println(ftpClient.getReplyCode() + " Switching to Binary mode.");
  79. } catch (IOException e) {
  80. e.printStackTrace();
  81. }
  82. } // end binary
  83. else if (command.equals("ascii")) {
  84. try {
  85. ftpClient.setFileType(FTP.ASCII_FILE_TYPE);
  86. System.out.println(ftpClient.getReplyCode() + " Switching to ASCII mode.");
  87. } catch (IOException e) {
  88. e.printStackTrace();
  89. }
  90. } // end ascii
  91. else if (command.equals("pwd")) {
  92. try {
  93. System.out.println(ftpClient.printWorkingDirectory());
  94. } catch (IOException e) {
  95. e.printStackTrace();
  96. }
  97. } // end pwd
  98. else if (command.equals("quit")) {
  99. try {
  100. ftpClient.logout();
  101. System.out.println(ftpClient.getReplyCode() + " Goodbye.");
  102. break;
  103. } catch (IOException e) {
  104. e.printStackTrace();
  105. }
  106. } // end quit
  107. else if (command.equals("put")) {
  108. String p1 = str.split(" ")[1];
  109. String p2 = str.split(" ")[2];
  110. File putFile = new File(p2);
  111. InputStream inputStream = null;
  112. try {
  113. inputStream = new FileInputStream(putFile);
  114. boolean result = ftpClient.storeFile(p1, inputStream);
  115. if (result == true) {
  116. System.out.println("업로드 성공");
  117. } else {
  118. System.out.println("업로드 실패");
  119. }
  120. } catch (IOException e) {
  121. e.printStackTrace();
  122. } finally {
  123. if (inputStream != null) {
  124. try {
  125. inputStream.close();
  126. } catch (IOException e) {
  127. e.printStackTrace();
  128. }
  129. }
  130. }
  131. } // end put
  132. else if (command.equals("get")) {
  133. String p1 = str.split(" ")[1];
  134. String p2 = str.split(" ")[2];
  135. File getFile = new File(p2);
  136. OutputStream outputStream = null;
  137. try {
  138. outputStream = new FileOutputStream(getFile);
  139. boolean result = ftpClient.retrieveFile(p1, outputStream);
  140. if (result == true) {
  141. System.out.println("다운로드 성공");
  142. } else {
  143. System.out.println("다운로드 실패");
  144. }
  145. } catch (FileNotFoundException e1) {
  146. e1.printStackTrace();
  147. } catch (IOException e) {
  148. e.printStackTrace();
  149. } finally {
  150. if (outputStream != null) {
  151. try {
  152. outputStream.close();
  153. } catch (IOException e) {
  154. e.printStackTrace();
  155. }
  156. }
  157. }
  158. } // end get
  159. else if (command.equals("delete")) {
  160. String file = str.split(" ")[1];
  161. try {
  162. ftpClient.deleteFile(file);
  163. } catch (IOException e) {
  164. e.printStackTrace();
  165. }
  166. } // end rm
  167. else if (command.equals("ls")) {
  168. String[] files = null;
  169. try {
  170. files = ftpClient.listNames();
  171. for (int i = 0; i < files.length; i++) {
  172. System.out.println(files[i]);
  173. }
  174. } catch (IOException e) {
  175. e.printStackTrace();
  176. }
  177. } // end ls
  178. else if (command.equals("dir")) {
  179. FTPFile[] files = null;
  180. try {
  181. files = ftpClient.listFiles();
  182. for (int i = 0; i < files.length; i++) {
  183. System.out.println(files[i]);
  184. }
  185. } catch (IOException e) {
  186. e.printStackTrace();
  187. }
  188. } // end dir
  189. } // end while
  190. try {
  191. ftpClient.disconnect();
  192. } catch (IOException e) {
  193. e.printStackTrace();
  194. } finally {
  195. scanner.close();
  196. }
  197. System.exit(0);
  198. }
  199. }

 

MySFTPClient.java

  1. package program;
  2. import java.security.KeyPairGenerator;
  3. import java.security.NoSuchAlgorithmException;
  4. import java.security.Security;
  5. import java.util.Scanner;
  6. import java.util.Vector;
  7. import javax.crypto.KeyAgreement;
  8. import org.bouncycastle.jce.provider.BouncyCastleProvider;
  9. import com.jcraft.jsch.Channel;
  10. import com.jcraft.jsch.ChannelSftp;
  11. import com.jcraft.jsch.JSch;
  12. import com.jcraft.jsch.JSchException;
  13. import com.jcraft.jsch.Session;
  14. import com.jcraft.jsch.SftpException;
  15. public class MySFTPClient {
  16. public void start() {
  17. // https://lahuman.jabsiri.co.kr/152
  18. // DH알고리즘을 쓰기위한 코드
  19. Security.addProvider(new BouncyCastleProvider());
  20. try {
  21. KeyPairGenerator.getInstance("DH");
  22. } catch (NoSuchAlgorithmException e1) {
  23. e1.printStackTrace();
  24. }
  25. try {
  26. KeyAgreement.getInstance("DH");
  27. } catch (NoSuchAlgorithmException e1) {
  28. e1.printStackTrace();
  29. }
  30. Session session = null;
  31. Channel channel = null;
  32. JSch jsch = new JSch();
  33. Scanner scanner = new Scanner(System.in);
  34. System.out.print("계정 입력: ");
  35. String username = scanner.nextLine();
  36. System.out.print("호스트 주소 입력: ");
  37. String host = scanner.nextLine();
  38. System.out.print("비밀번호 입력: ");
  39. String password = scanner.nextLine();
  40. try {
  41. // 세션 객체 생성
  42. session = jsch.getSession(username, host, 22);
  43. // 비밀번호설정
  44. session.setPassword(password);
  45. // 호스트 정보를 검사하지 않음
  46. session.setConfig("StrictHostKeyChecking", "no");
  47. // 세션접속
  48. session.connect();
  49. // sftp채널열기
  50. channel = session.openChannel("sftp");
  51. // 채널접속
  52. channel.connect();
  53. System.out.println("Connected to user@" + host);
  54. } catch (JSchException e) {
  55. e.printStackTrace();
  56. System.out.println("접속에 실패했습니다.");
  57. // 실패시 시스템 종료
  58. System.exit(0);
  59. }
  60. ChannelSftp channelSftp = (ChannelSftp) channel;
  61. while (true) {
  62. System.out.print("sftp> ");
  63. String str = "";
  64. str = scanner.nextLine();
  65. String[] params = str.split(" ");
  66. String command = params[0];
  67. if (command.equals("cd")) {
  68. String p1 = params[1];// 스플릿의 과부하를 줄인다..왜? 변수명으로 바꼈자나
  69. try {
  70. channelSftp.cd(p1);
  71. } catch (SftpException e) {
  72. System.out.println("Couldn't stat remote file: No such file or directory");
  73. }
  74. } // end cd
  75. else if (command.equals("lcd")) {
  76. // lcd C:\Users\solulink
  77. String p1 = params[1];
  78. try {
  79. channelSftp.lcd(p1);
  80. } catch (SftpException e) {
  81. System.out.println("Couldn't change local directory to " + p1 + ": No such file or directory");
  82. }
  83. } // end lcd
  84. else if (command.equals("pwd")) {
  85. try {
  86. System.out.println("Remote working directory: " + channelSftp.pwd());
  87. } catch (SftpException e) {
  88. e.printStackTrace();
  89. }
  90. } // end pwd
  91. else if (command.equals("lpwd")) {
  92. // lpwd
  93. System.out.println("Local working directory: " + channelSftp.lpwd());
  94. } // end lpwd
  95. else if (command.equals("get")) {
  96. try {
  97. if (params.length == 2) {
  98. channelSftp.get(params[1]);
  99. } else {
  100. channelSftp.get(params[1], params[2]);
  101. }
  102. } catch (SftpException e) {
  103. System.out.println("Ex)get centos.txt C:\\Users\\solulink");
  104. }
  105. } // end get
  106. else if (command.equals("put")) {
  107. String p1 = str.split(" ")[1];
  108. try {
  109. channelSftp.put(p1);
  110. } catch (SftpException e) {
  111. System.out.println("Ex)put window.txt");
  112. }
  113. } // end put
  114. else if (command.equals("ls") || command.equals("dir")) {
  115. String path = ".";
  116. try {
  117. // 가변길이의 배열
  118. Vector vector = channelSftp.ls(path);
  119. if (vector != null) {
  120. for (int i = 0; i < vector.size(); i++) {
  121. Object obj = vector.elementAt(i);
  122. if (obj instanceof ChannelSftp.LsEntry) {
  123. System.out.println(((ChannelSftp.LsEntry) obj).getLongname());
  124. }
  125. }
  126. }
  127. } catch (SftpException e) {
  128. System.out.println(e.toString());
  129. }
  130. } // end ls
  131. else if (command.equals("rm")) {
  132. try {
  133. String p1 = str.split(" ")[1];
  134. channelSftp.rm(p1);
  135. } catch (SftpException e) {
  136. System.out.println("Couldn't delete file: No such file or directory");
  137. }
  138. } // end rm
  139. else if (command.equals("mkdir")) {
  140. String p1 = str.split(" ")[1];
  141. try {
  142. channelSftp.mkdir(p1);
  143. } catch (SftpException e) {
  144. e.printStackTrace();
  145. }
  146. } // end mkdir
  147. else if (command.equals("rmdir")) {
  148. String p1 = str.split(" ")[1];
  149. try {
  150. channelSftp.rmdir(p1);
  151. } catch (SftpException e) {
  152. System.out.println("Couldn't remove diretory: No such file or directory");
  153. }
  154. } // end rmdir
  155. else if (command.equals("chmod")) {
  156. // 접근권한 설정
  157. // chmod 777 window.txt(rwx:7 x:1 wx:3 r-x:5)
  158. String p1 = str.split(" ")[1];
  159. String p2 = str.split(" ")[2];
  160. try {
  161. channelSftp.chmod(Integer.parseInt(p1), p2);
  162. } catch (NumberFormatException e) {
  163. e.printStackTrace();
  164. } catch (SftpException e) {
  165. e.printStackTrace();
  166. }
  167. } // end chmod
  168. else if (command.equals("chown")) {
  169. // 파일소유권변경->일반계정에 root권한 부여(vi /etc/passwd->UID와GID변경)
  170. // 리눅스에서 cat /etc/passwd
  171. // jinpyolee : 1000 sftpuser : 1004
  172. // chown 1000 window.txt
  173. String p1 = str.split(" ")[1];
  174. String p2 = str.split(" ")[2];
  175. try {
  176. channelSftp.chown(Integer.parseInt(p1), p2);
  177. } catch (NumberFormatException e) {
  178. e.printStackTrace();
  179. } catch (SftpException e) {
  180. e.printStackTrace();
  181. }
  182. } // end chown
  183. else if (command.equals("ln") || (command.equals("symlink"))) {
  184. // 링크파일 생성(rwxrwxrwx, 리눅스에서 하늘색으로 나옴)
  185. // ln window.txt win.txt
  186. String p1 = str.split(" ")[1];
  187. String p2 = str.split(" ")[2];
  188. try {
  189. channelSftp.symlink(p1, p2);
  190. } catch (SftpException e) {
  191. e.printStackTrace();
  192. }
  193. } // end ln
  194. else if (command.equals("quit")) {
  195. channelSftp.quit();
  196. // 반복문 나가서 종료
  197. break;
  198. } // end quit
  199. else {
  200. System.out.println("Invalid command.");
  201. }
  202. } // end while
  203. // 연결해제
  204. channelSftp.disconnect();
  205. // 스캐너자원반납
  206. scanner.close();
  207. // 시스템종료
  208. System.exit(0);
  209. }
  210. }// end class

 

메인은 ProgramStart.java에 있습니다.

 

FTP로 서버에 접속한 모습

FTP를 이용해 서버(CentOS)에 접속한 모습입니다.

구현된 명령어 사용은 생략하겠습니다.

 

SFTP로 서버에 접속한 모습

SFTP를 이용해 서버에 접속한 모습입니다.

 

연결 순서가 조금 다르긴하나 큰 차이는 없습니다.

 

연결후 CMD창에서와 같이 명령어를 사용하면 됩니다.



출처: https://thefif19wlsvy.tistory.com/5 [FIF's 코딩팩토리]

반응형
Comments