서버
package net;
import java.io.DataInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
//파일 보관 서버(FTP 서버)
public class file_server {
public static void main(String[] args) {
new ftp_server(10000);
}
}
class ftp_server{
int port = 0; //오픈할 서버 포트
Socket sk = null; //Client가 접속할 수 있도록 서버를 유지시키는 역할
ServerSocket ss = null; //해당 포트를 이용하여 서버 오픈
InputStream is = null; //Client에서 받아오는 파일
FileOutputStream fs = null; //Server PC 저장하는 파일
public ftp_server(int p) { //필드에 있는 port변수에 값을 이관
this.port = p;
this.data(); //은닉화 메소드를 실행
}
private void data() { //서버 가동 및 클라이언트에서 보낸 파일을 받는 역할
try{
//FileOutputStream => 파일이 없어도 생성 시켜줌
//FileWrite => create로 생성해야함
//해당 PC에서 포트를 오픈
this.ss = new ServerSocket(this.port);
this.sk = this.ss.accept(); //클라이언트 접속 대기
System.out.println("[서버 가동중]");
String url = "/Users/nayeong/Documents/java_etc/ftp/"; //클라이언트에서 전송된 파일 저장소
//클라이언트가 전송한 파일을 읽어들여서 체크하는 코드
this.is = this.sk.getInputStream();
//파일명을 체크하는 코드
//DataInputStream (파일명 + 파일용량)
//DataInputStream은 Client에서 DataOutputStream를 사용해야 의미있음
DataInputStream ds = new DataInputStream(this.is);
String file_name = ds.readUTF(); //readUTF : 문자로 전송된 값 읽어옴
byte data[] = new byte[2097152]; //2MB씩 파일을 체크
// int by = this.is.read(data);
// String filename = new String(data, 0, by, StandardCharsets.UTF_8);
// System.out.println(filename);
/* ASCII 향태의 파일 경우 해당 내용을 확인하여 출력할 수 있음(Bynary X)
this.is.read(data);
System.out.println(this.is.available()); //전송 파일 용량 체크
*/
this.fs = new FileOutputStream(url+"ftp_"+ file_name); //경로만 쓰면 저장불가능 파일명까지 넣어야 복사 가능
int filesize = 0;
while((filesize = this.is.read(data)) != -1) {
this.fs.write(data,0,filesize);
this.fs.flush();
}
System.out.println("정상적으로 업로드 완료되었습니다.");
ds.close();
this.fs.close();
this.is.close();
this.sk.close();
}catch (Exception e) {
System.out.println("서버 포트 충돌로 인하여 오류 발생");
}
}
}
클라이언트
package net;
import java.io.BufferedInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.util.Scanner;
//파일 업로드 Client(FTP 접속 및 파일 전송)
public class file_client {
public static void main(String[] args) {
new ftp_client("172.30.1.34", 10000); //서버 ip 및 접속 포트
}
}
class ftp_client{
String ip = null; //서버 ip 정보
int port = 0; //서버 port 정보
Socket sk = null; //서버 연결
InputStream is = null; //자신의 PC에 있는 파일을 읽어
OutputStream os = null; //서버로 전송하는 역할
Scanner sc = null; //자신의 PC파일 경로
public ftp_client(String serverip, int p) {
this.ip = serverip; //필드에 ip 이관
this.port = p; //필드에 port 이관
this.sc = new Scanner(System.in);
this.files(); //은닉화 파일 전송을 하는 메소드를 호출
}
private void files() {
//IO와 관계없는 Exception은 catch로 핸들링 가능 IO는 throws로 핸들링
//JAVA OOP, 예외처리 => catch
//IO, Net => throws
//try안에서 IO나 Net의 객체가 new로 인스턴스화되면 catch에 IOException작동 가능
/* Java Exception Tree 한번 찾아보기 알아두면 좋음
Exception - RuntimeException - IndexOutOfBoundsException
- IOException - FileNotFoundException
- SocketException
- Error - NumberFormat
*/
try {
this.sk = new Socket(this.ip, this.port); //여기서 new로 Socket 인스턴스화 했으니 예외처리 가능
System.out.println("업로드할 이미지 경로를 입력하세요 : ");
String url = this.sc.nextLine(); //사용자가 지정하는 경로 및 파일명
File f = new File(url); //"파일명"을 로드하기 위해서 (사용자 경로 + 파일명)
//자신의 PC에 있는 파일을 읽어들임
this.is = new FileInputStream(url); //여기서 new로 FileInputStream 인스턴스화 했으니 예외처리 가능
BufferedInputStream bs = new BufferedInputStream(this.is);
byte img[] = new byte[bs.available()];
bs.read(img);
//서버로 전송
/*
//byte로 전송(파일전체 크기용량 전송)
//얘는 파일 이름을 못보냄
this.os = this.sk.getOutputStream();
this.os.write(img);
this.os.flush();
this.os.close();
*/
//파일명을 포함하여 전송
this.os = this.sk.getOutputStream();
/*
DataOutputStream : 네트워크 전용 Stream
byte로 전송도 가능함
추가로 write에 다양한 기능 탑재되어있음
파일명, 데이터 타입, 데이터 속성, 데이터 용량...
*/
DataOutputStream ds = new DataOutputStream(this.os);
ds.writeUTF(f.getName()); //파일명
ds.write(img); //파일명 용량
ds.flush();
ds.close();
bs.close();
this.is.close();
this.sc.close();
System.out.println("파일 전송이 완료되었습니다.");
}
//IOException : IO 및 네트워크 전체를 다루는 예외처리
//FileNotFoundException : 파일 못찾은 예외처리
catch (FileNotFoundException ie) { //여기 IOException 넣으면 오류남 소켓예외의 부모라서 IOException쓸거면 소켓예외를 위로 올려주기
System.out.println("파일 경로 및 파일명이 잘못되었습니다.");
}
//네트워크 접속에 대한 예외처리
catch (SocketException se) {
System.out.println("서버에 접속하지 못하였습니다.");
}
//최고 부모 역할을 하는 예외처리
catch (Exception e) {
System.out.println("코드 문제로 인하여 버그가 발생하였습니다.");
}
}
}