FTP (파일 전송 프로토콜 파일 전송 프로토콜)는 인터넷에서 파일을 전송하는 데 사용되는 프로토콜입니다. 인터넷의 FTP 서버를 통해 파일을 업로드 (업로드) 또는 다운로드 (다운로드) 할 수 있습니다. FTP는 실시간 온라인 서비스입니다. 사용하기 전에 서비스가 포함 된 사용자 (사용자 이름 및 비밀번호) 여야합니다. 작업 할 때 클라이언트는 먼저 서버 인 컴퓨터에 로그인해야합니다. 로그인 한 후 사용자는 파일 검색 및 파일 전송 및 현재 작업 디렉토리 변경, 열 파일 디렉토리 변경, 전송 매개 변수 설정 및 전송 파일 등과 같은 기타 관련 작업을 수행 할 수 있습니다. FTP를 사용하여 텍스트 파일, 이진 실행 파일, 이미지 파일, 사운드 파일 및 데이터 압축 파일과 같은 모든 유형의 파일을 전송합니다.
FTP 명령
FTP의 주요 작업은 다양한 명령을 기반으로합니다. 일반적으로 사용되는 명령은 다음과 같습니다.
ASCⅱ (텍스트) 및 이진 바이너리 모드를 포함하는 전송 모드를 설정합니다.
원격 컴퓨터의 현재 디렉토리를 변경 또는 표시하는 디렉토리 작동 (CD, DIR/LS 명령);
연결 작동, Open 명령은 원격 컴퓨터와의 연결을 설정하는 데 사용됩니다. Close 명령은 연결을 닫는 데 사용됩니다.
보낸 작업, PUT 명령은 파일을 원격 컴퓨터로 전송하는 데 사용됩니다. PUT 명령은 여러 파일을 원격 컴퓨터로 전송하는 데 사용됩니다.
GET 작업, GET 명령은 하나의 파일을 수신하는 데 사용됩니다. mgget 명령은 여러 파일을 수신하는 데 사용됩니다.
import java.net.socket; import org.apache.log4j.logger; /** * 역할 - 서버 A * @Author Leon * */public class servera {public static void main (String [] args) {Final String f_dir = "c :/test"; // 루트 경로 최종 int 포트 = 22; // 포트 번호 logger를 듣습니다. getRootLogger (); 로거 로거 = logger.getLogger ( "com"); {serversocket s = new serversocket (port); logger.info ( "서버에 연결 ..."); logger.info ( "연결된 성공적인! 로컬 포트 :"+s.getlocalport ()+". 기본 디렉토리 : '"+f_dir+"'."); while (true) {// 클라이언트 요청 소매 수락 소매 클라이언트 = s.accept (); // 서비스 스레드 작성 new ClientThread (client, f_dir) .start (); }} catch (예외 e) {logger.error (e.getMessage ()); for (stackTraceElement Ste : e.getStackTrace ()) {logger.error (Ste.ToString ()); }}}} import java.io.bufferedReader; import java.io.file; import java.io.filenotfoundException; import java.io.ioexception; import java.io.inputstream; import java.io.inputStreamReader; import java.io.outputStream; import java.io.printwriter; import java.io.randomaccessfile; import java.net.connectException; import java.net.inetAddress; import java.net.serversocket; import java.net.socket; import java.net.unknownhostexception; import java.nio.charset.charset; java.util.random import; import org.apache.log4j.logger; /** * 클라이언트 서브 스레드 클래스 * @Author Leon * */public class ClientThread는 스레드 {private socket socketclient; // 클라이언트 소켓 개인 로거 로그거; // 로그인 객체 개인 문자열 dir; // 절대 경로 개인 문자열 pdir = "/"; // 상대 경로 개인 정적 무작위 생성기 = new Random (); 고객; this.dir = f_dir; } @override public void run () {logger.getRootLogger (); logger = logger.getLogger ( "com"); 입력 스트림은 = null입니다. OutputStream os = null; try {is = socketclient.getInputStream (); os = socketclient.getoutPutStream (); } catch (ioException e) {logger.error (e.getMessage ()); for (stackTraceElement Ste : e.getStackTrace ()) {logger.error (Ste.ToString ()); }} bufferedReader br = new bufferedReader (new inputStreamReader (is, charset.forname ( "utf-8"))); printwriter pw = 새로운 printwriter (OS); String clientip = socketclient.getInetAddress (). toString (). substring (1); // 레코드 클라이언트 IP 문자열 username = "로그인하지 않음"; // username string password = ""; // password string 명령 = ""; // command boolean loginstus = // login wind world login_warning = "; String str = ""; // 명령 내용 문자열 int port_high = 0; int port_low = 0; String ret_ip = ""; // 수신 파일 소켓 tempsocket = null의 IP 주소; // 환영 메시지 인쇄 pw.println ( "220-ftp 서버 A 버전 1.0 Leon Guo가 작성한 버전 1.0"); pw.flush (); logger.info ( "("+username+") ("+clientip+")> 연결, 환영 메시지 보내기 ..."); logger.info ( "("+username+") ("+clientip+")> 220-ftp 서버 A 버전 1.0 Leon Guo가 작성한 버전 1.0"); 부울 b = 참; while (b) {try {// 사용자 명령 = br.readline ()에 의해 입력 된 명령을 가져옵니다. if (null == command) break; } catch (ioexception e) {pw.println ( "331 명령을 얻지 못했다"); pw.flush (); logger.info ( "("+username+") ("+clientip+")> 331 명령을 얻지 못했습니다"); logger.error (e.getMessage ()); for (stackTraceElement Ste : e.getStackTrace ()) {logger.error (Ste.ToString ()); } b = 거짓; } /** 액세스 제어 명령* / // 사용자 명령 if (command.toupperCase (). startSwith ( "user")) {logger.info ( "(로그인) ("+clientip+")>"+명령); username = command.substring (4) .trim (); if ( "". Equals (username)) {pw.println ( "501 구문 오류"); pw.flush (); logger.info ( "(로그인되지 않음) ("+clientip+")> 501 구문 오류"); username = "로그인되지 않음"; } else {pw.println ( " + username에 필요한 331 비밀번호); pw.flush (); logger.info ( "(로그인되지 않음) ("+clientip+")> 331"+username에 필요한 비밀번호); } loginstus = false; } // end user // pass command else if (command.toupperCase (). startSwith ( "pass")) {logger.info ( "(로그인되지 않음) ("+clientip+")>"+명령); password = command.substring (4) .trim (); if (username.equals ( "root") && password.equals ( "root")) {pw.println ( "230 로그온"); pw.flush (); logger.info ( "("+username+") ("+clientip+")> 230 로그온"); // logger.info ( "client"+clientip+""사용자 로그인 "); loginStus = true;} else {pw.println ("530 login 또는 password right! "); pw.flush (); logger.info ("( "+clientip+")> 530 login 또는 password rect! " // pwd else else if (command.toupperCase (). startSwith ( "pwd")) { "+username+") ( "+clientip+")> "+명령) {// logger.info ("user "+"); pw.println ( "257 /" "+pdir+" /"는 현재 디렉토리입니다. } else {pw.println (login_warning); pw.flush (); logger.info ( "("+username+") ("+clientip+")>"+login_warning); }} // end pwd // cwd 명령 else if (command.toupperCase (). startSwith ( "cwd")) {logger.info ( "("+username+") ("+clientip+")>"+command); if (loginstus) {str = command.substring (3) .trim (); if ( "". equals (str)) {pw.println ( "250 파손 클라이언트 감지, cwd에 대한 인수 누락 /" "+pdir+" /"는 현재 디렉토리입니다."); pw.flush (); logger.info ( "("+username+") ("+clientip+")> 250 클라이언트 감지, cwd에 대한 인수 누락,"+pdir+"/"/");} else {// 디렉토리에 문자열 tmpdir = dir+"/"+str; file file = new File (tmpdir); dir+"/"+str; 현재 디렉토리 "); pw.flush (); logger.info ( "("+username+") ("+clientip+")> 250 cwd 성공./"+pdir+"/"는 현재 디렉토리입니다.} else {// 디렉토리는 pw.println ( "550 cwd 실패./" "+pdir+": directory find. "); logger.info ( "("+username+") ("+clientip+")> 550 cwd 실패. /"+pdir+" /": 디렉토리를 찾을 수 없음 "); }} else {pw.println (login_warning); pw.flush (); logger.info ( "("+username+") ("+clientip+")>"+login_warning); }} // end cwd // quit 명령 else if (command.toupperCase (). startSwith ( "quit")) {logger.info ( "("+username+") ("+clientip+")>"+command); b = 거짓; pw.println ( "221 Goodbye"); pw.flush (); logger.info ( "("+username+") ("+clientip+")> 221 Goodbye"); try {ordle.currentthread (); Thread.sleep (1000); } catch (InterruptedException e) {logger.error (e.getMessage ()); for (stackTraceElement Ste : e.getStackTrace ()) {logger.error (Ste.ToString ()); }}} // end quit /** 전송 매개 변수 명령* / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /// port command* / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /// port parameter command 송금* // port command* / / / / / / / / / / / / / / / / / /// port command* / / / / / / / /// port command는 mode에서 데이터를 적극적으로 전송합니다 if (command.toupperCase (). startSwith ( "port")) {logger.info ( "("+username+") ("+clientip+")>"+command); if (loginstuts) {try {str = command.substring (4) .trim (); port_low = integer.parseint (str.substring (str.lastindexof ( ",")+1)); port_high = integer.parseint (str.substring (0, str.lastindexof ( ",")) .substring (str.substring (0, str.lastindexof ( ",")). lastIndexof ( ",")+1); String str1 = str.substring (0, str.substring (0, str.lastindexof ( ",")). lastindexof ( ",")); ret_ip = str1.replace ( ",", "."); try {// 활성 모드에서 소켓 온도 = 새로운 소켓 (Ret_ip, port_high * 256 + port_low); // logger.info ( "user"+clientip+":"+username+"execute port 명령"); pw.println ( "200 포트 명령 성공"); pw.flush (); logger.info ( "("+username+") ("+clientip+")> 200 포트 명령 성공"); } catch (connectException ce) {pw.println ( "425 데이터 연결을 열 수 없습니다"); pw.flush (); logger.info ( "("+username+") ("+clientip+")> 425 데이터 연결을 열 수 없습니다."); logger.error (ce.getMessage ()); for (stackTraceElement Ste : ce.getStacktrace ()) {logger.error (Ste.ToString ()); }} catch (unknownHostException e) {logger.error (e.getMessage ()); for (stackTraceElement Ste : e.getStackTrace ()) {logger.error (Ste.ToString ()); }} catch (ioexception e) {logger.error (e.getMessage ()); for (stackTraceElement Ste : e.getStackTrace ()) {logger.error (Ste.ToString ()); }}} catch (numberformatexception e) {pw.println ( "503 불량 명령 시퀀스"); pw.flush (); logger.info ( "("+username+") ("+clientip+")> 503 잘못된 명령 시퀀스"); logger.error (e.getMessage ()); for (stackTraceElement Ste : e.getStackTrace ()) {logger.error (Ste.ToString ()); }}} else {pw.println (login_warning); pw.flush (); logger.info ( "("+username+") ("+clientip+")>"+login_warning); }} // 종료 포트 // pasv 명령, 수동 모드 전송 데이터 if (command.toupperCase (). startSwith ( "pasv")) {logger.info ( "("+username+") ("+clientip+")>"+command); if (loginstuts) {serversocket ss = null; while (true) {// 서버 무료 port_high = 1 + generator.nextint (20); port_low = 100 + generator.nextint (1000); 시도 {// 서버 바인딩 포트 SS = New Serversocket (port_high * 256 + port_low); 부서지다; } catch (ioException e) {계속; }} // logger.info ( "user"+clientip+":"+username+"execute pasv command"); inetAddress i = null; {i = inetAddress.getLocalHost (); } catch (unknownHostException e1) {e1.printstacktrace (); } pw.println ( "227 수동 모드로 들어갑니다 ("+i.gethostaddress (). replace ( ".", ","), "+port_high+", "+port_low+"); pw.flush (); logger.info ( "("+username+") ("+clientip+")> 227 패시브 모드로 들어갑니다 ("+i.gethostaddress (). REPLACE ( ".", ",")+","+port_high+","+port_low+"); 시도 {// 소켓 tempsocket에서 수동 모드 = ss.accept (); ss.close (); } catch (ioException e) {logger.error (e.getMessage ()); for (stackTraceElement Ste : e.getStackTrace ()) {logger.error (Ste.ToString ()); }}} else {pw.println (login_warning); pw.flush (); logger.info ( "("+username+") ("+clientip+")>"+login_warning); }} // end pasv // ret command else if (command.toupperCase (). startSwith ( "ret")) {logger.info ( "("+username+") ("+clientip+")>"+명령); if (loginstuts) {str = command.substring (4) .trim (); if ( "". Equals (str)) {pw.println ( "501 구문 오류"); pw.flush (); logger.info ( "("+username+") ("+clientip+")> 501 구문 오류"); } else {try {pw.println ( "파일 전송을위한 150 개 열기 데이터 채널"); pw.flush (); logger.info ( "("+username+") ("+clientip+")> 150 파일 전송을위한 데이터 채널 열기"); RandomAccessFile Outfile = null; outputStream outsocket = null; {// 지정된 이름 outfile = new randomAccessFile (dir+"/"+str, "r")과 함께 임의의 액세스 파일 스트림을 작성하고 쓸 수 있습니다 (선택 사항); OutSocket = tempsocket.getOutputStream (); } catch (filenotfoundException e) {logger.error (e.getMessage ()); for (stackTraceElement Ste : e.getStackTrace ()) {logger.error (Ste.ToString ()); }} catch (ioexception e) {logger.error (e.getMessage ()); for (stackTraceElement Ste : e.getStackTrace ()) {logger.error (Ste.ToString ()); }} 바이트 바이트 버퍼 [] = 새로운 바이트 [1024]; int 길이; {while ((길 } outsocket.close (); Outfile.close (); tempsocket.close (); tempsocket.close (); } catch (ioException e) {logger.error (e.getMessage ()); for (stackTraceElement Ste : e.getStackTrace ()) {logger.error (Ste.ToString ()); }} // logger.info ( "user"+clientip+":"+username+"execute ret 명령"); pw.println ( "226 Transfer OK"); pw.flush (); logger.info ( "("+username+") ("+clientip+")> 226 전송 확인"); } catch (예외 e) {pw.println ( "503 불량 명령 순서"); pw.flush (); logger.info ( "("+username+") ("+clientip+")> 503 잘못된 명령 시퀀스"); logger.error (e.getMessage ()); for (stackTraceElement Ste : e.getStackTrace ()) {logger.error (Ste.ToString ()); }}} else {pw.println (login_warning); pw.flush (); logger.info ( "("+username+") ("+clientip+")>"+login_warning); }} // end ret // stor scor command else if (command.toupperCase (). startSwith ( "stor")) {logger.info ( "("+username+") ("+clientip+")>"+command); if (loginstuts) {str = command.substring (4) .trim (); if ( "". Equals (str)) {pw.println ( "501 구문 오류"); pw.flush (); logger.info ( "("+username+") ("+clientip+")> 501 구문 오류"); } else {try {pw.println ( "파일 전송을위한 150 개 열기 데이터 채널"); pw.flush (); logger.info ( "("+username+") ("+clientip+")> 150 파일 전송을위한 데이터 채널 열기"); randomaccessfile infile = null; inputStream insocket = null; try {infile = new randomaccessfile (dir+"/"+str, "rw"); insocket = tempsocket.getInputStream (); } catch (filenotfoundException e) {logger.error (e.getMessage ()); for (stackTraceElement Ste : e.getStackTrace ()) {logger.error (Ste.ToString ()); }} catch (ioexception e) {logger.error (e.getMessage ()); for (stackTraceElement Ste : e.getStackTrace ()) {logger.error (Ste.ToString ()); }} 바이트 바이트 버퍼 [] = 새로운 바이트 [1024]; int 길이; try {while ((length = insocket.read (bytebuffer))! = -1) {infile.write (Bytebuffer, 0, length); } insocket.close (); infile.close (); tempsocket.close (); } catch (ioException e) {logger.error (e.getMessage ()); for (stackTraceElement Ste : e.getStackTrace ()) {logger.error (Ste.ToString ()); }} // logger.info ( "user"+clientip+":"+username+"execute store 명령"); pw.println ( "226 Transfer OK"); pw.flush (); logger.info ( "("+username+") ("+clientip+")> 226 전송 확인"); } catch (예외 e) {pw.println ( "503 불량 명령 순서"); pw.flush (); logger.info ( "("+username+") ("+clientip+")> 503 잘못된 명령 시퀀스"); logger.error (e.getMessage ()); for (stackTraceElement Ste : e.getStackTrace ()) {logger.error (Ste.ToString ()); }}}} else {pw.println (login_warning); pw.flush (); logger.info ( "("+username+") ("+clientip+")>"+login_warning); }} // end stor // nlst 명령 else if (명령 .toupperCase (). startSwith ( "nlst")) {logger.info ( "("+username+") ("+clientip+")>"+command); if (loginstuts) {try {pw.println ( "디렉토리 목록의 150 개 열기"); pw.flush (); logger.info ( "("+username+") ("+clientip+")> 150 디렉토리 목록의 데이터 채널 열기"); Printwriter pwr = null; try {pwr = new printwriter (tempsocket.getOutputStream (), true); } catch (ioexception e1) {e1.printstacktrace (); } 파일 파일 = 새 파일 (dir); String [] 분비 = 새 문자열 [10]; 분비 = file.list (); for (int i = 0; i <dirstructure.length; i ++) {pwr.println (Dirstructure [i]); } try {tempsocket.close (); pwr.close (); } catch (ioException e) {logger.error (e.getMessage ()); for (stackTraceElement Ste : e.getStackTrace ()) {logger.error (Ste.ToString ()); }} // logger.info ( "user"+clientip+":"+username+"execute nlst command"); pw.println ( "226 Transfer OK"); pw.flush (); logger.info ( "("+username+") ("+clientip+")> 226 전송 확인"); } catch (예외 e) {pw.println ( "503 불량 명령 순서"); pw.flush (); logger.info ( "("+username+") ("+clientip+")> 503 잘못된 명령 시퀀스"); logger.error (e.getMessage ()); for (stackTraceElement Ste : e.getStackTrace ()) {logger.error (Ste.ToString ()); }}} else {pw.println (login_warning); pw.flush (); logger.info ( "("+username+") ("+clientip+")>"+login_warning); }} // end nlst // list 명령 else if (command.toupperCase (). startSwith ( "list")) {logger.info ( "("+username+") ("+clientip+")>"+명령); if (loginstuts) {try {pw.println ( "디렉토리 목록의 150 개 열기"); pw.flush (); logger.info ( "("+username+") ("+clientip+")> 150 디렉토리 목록의 데이터 채널 열기"); Printwriter pwr = null; try {pwr = new printwriter (tempsocket.getOutputStream (), true); } catch (ioException e) {logger.error (e.getMessage ()); for (stackTraceElement Ste : e.getStackTrace ()) {logger.error (Ste.ToString ()); }} ftputil.getDetaillist (pwr, dir); try {tempsocket.close (); pwr.close (); } catch (ioException e) {logger.error (e.getMessage ()); for (stackTraceElement Ste : e.getStackTrace ()) {logger.error (Ste.ToString ()); }} // logger.info ( "user"+clientip+":"+username+"execute list 명령"); pw.println ( "226 Transfer OK"); pw.flush (); logger.info ( "("+username+") ("+clientip+")> 226 전송 확인"); } catch (예외 e) {pw.println ( "503 불량 명령 순서"); pw.flush (); logger.info ( "("+username+") ("+clientip+")> 503 잘못된 명령 시퀀스"); logger.error (e.getMessage ()); for (stackTraceElement Ste : e.getStackTrace ()) {logger.error (Ste.ToString ()); }}} else {pw.println (login_warning); pw.flush (); logger.info ( "("+username+") ("+clientip+")>"+login_warning); }} // 종료 목록 // 불법 명령을 입력합니다. pw.println ( "500 구문 오류, 명령을 인식 할 수없는 명령"); pw.flush (); logger.info ( "("( "+username+")) ( "+clientip+")> 500 구문 오류, 명령 인식이없는 명령 "); }} // try {logger.info ( "("( "+username+"( "+username+")); "); // logger.info ("user "+clientip+": "+username+"exit "); br.close (); pw.close (); if (null!); tempsocket.close ()}} {getmessage (); java.text.simpledateformat; directory./r/n ");} file [] files [] files = dir.listfiles (); String modifyDate; for (int i = 0; i <files.length; i ++) {new simpledateformat ("yyyy/mm/dd hh : mm : ss ") .format (files [i])); (파일 [i] .isdirectory ()) {pw.println ( "drwxr-xr-x ftp 0" + modifydate + "" + files [i] .getname ()) {pw.println ( "-rw----1 ftp" + 파일 () + " +" + " +" + " +" + " +" + " +" + " +" files [i]. getname ()) pw.flush (); log4j.appender.stdout.target = system.out log4j.appender.stdout.layout = org.apache.log4j.patternlayout log4j.appender.stdout.layout.conversionpattern = %d {절대} %5p %c {1} : %l- %m %n # output log4j.appender.d = org.apache.log4j.dailyrollingfileAppender log4j.appender.d.file = c : /logs/logs.log log4j.appender.d.append = true output log4j.appender.d.threshold = debug log4j.appender.d.layout = org.apchache log4j.appender.d.layout.layout.conversionpattern = %-d {yyyy-mm-dd hh : mm : ss} [ %t : %r]-[ %p] %m %n ### 예외 정보를 별도의 파일에 예외 정보 저장 ### appender.e = org.apache.log4j.daileppendender##applendendendendendendendendendendendendender#. log4j.appender.e.file = c : /logs/errors.log log4j.appender.e.append = true ## 오류 레벨 위의 출력 로그 만 있습니다 %-d {yyyy-mm-dd hh : mm : ss} [ %t : %r]-[ %p] %m %n위의 내용은 편집자가 귀하에게 소개 한 FTP 서버 기능 예제 코드의 Java 구현에 대한 관련 지식입니다. 나는 당신이 그것을 좋아하기를 바랍니다.