디지털 컨버전스/JAVA

[Java] review , File, 네트워크 - 채팅하기, 파일전송

gimyeondong 2020. 3. 9. 09:48

자바언어 소개&특성 -  https://www.tiobe.com/

 

Home | TIOBE - The Software Quality Company

Request Proof of Concept Request a proof of concept to have your product measured by TICS.

www.tiobe.com

범용성 문법

  • 변수 / 연산자 - 자료형 promotion casting size 등... + - * / =
  • 기본 입력 - Scanner
  • 제어문 - if / for / while / switch / break / continue
  • 난수 - 업앤다운 / 베스킨 / 경마게임 / 가위바위보
  • 배열 - 다량의 변수를 일괄 통제하는 문법 (반복문과 밀접)
  • 메서드 - 오버로딩 / 메서드의 구조

객체지향

  • 클래스 (설계도) / 인스턴스 (객체) / new
  • 초급 : 정보은닉 / getter&setter / Constuctor / this / static(병행처리 취약, 필요한 경우에만 : 프로그램 전체에서 사라지지않으며 대부분에서 쓰이는 경우)
  • 활용 : 라이브러리 활용하기 ( FTP4J / JLayer / JavaMail )
  • 중급 : 상속 (extends / 오버라이딩) / 다형성 / 추상화 (Abstract / Interface)
    • Collection Framework ( List (소량데이터, 중복허용, 순서유지) / Set (검색성능 뛰어남, 중복허용안함, 순서유지안함) / Map (Set+key) )
      • API < Library < Framework
      • API : 웹api 네이버지도, 프라이빗한 부분 보이지 않음
      • Library : 기능을 포함한 도구
      • Framework : 라이브러리가 다수 포함된 규약

 

네트워크

  • TCP / Socket / ServerSocket / IP / PORT / Stream / Server & Client 

강사님 서버에 클라이언트로 접속

import java.io.DataOutputStream;
import java.io.OutputStream;
import java.net.Socket;

import javax.swing.JOptionPane;

public class Client {
	public static void main(String[] args) {
		try {
			
			Socket sock  = new Socket("192.168.60.57", 50000);

			OutputStream os= sock.getOutputStream(); //보내기 통로 만들기
			DataOutputStream dos = new DataOutputStream(os); //통로 업그레이드
			
			dos.writeUTF("스트링상수");
			dos.flush();
		
			
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
}

채팅하기

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import javax.swing.JOptionPane;

public class Server {
	public static void main(String[] args) {
		String msg = null;
		try {
			ServerSocket server = new ServerSocket(50000);

			System.out.println("서버를 가동했습니다.");
			Socket sock = server.accept();
			System.out.println(sock.getInetAddress() + " 에서 연결");


			DataInputStream dis = 
					new DataInputStream(sock.getInputStream());
			DataOutputStream dos = 
					new DataOutputStream(sock.getOutputStream());

			while(true) {
				dos.writeUTF(JOptionPane.showInputDialog("보낼 메세지를 입력하세요"));
				dos.flush();
				System.out.println("나 : "+dos);
				System.out.println(sock.getInetAddress()+" : "+dis.readUTF());
			}

		}catch(Exception e) {
			e.printStackTrace();

		}
	}
}
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.OutputStream;
import java.net.Socket;

import javax.swing.JOptionPane;

public class Client {
	public static void main(String[] args) {
		try {

			Socket sock  = new Socket("192.168.60.19", 50000);

			DataInputStream dis = 
					new DataInputStream(sock.getInputStream());
			DataOutputStream dos = 
					new DataOutputStream(sock.getOutputStream());

			while(true) {
				dos.writeUTF(JOptionPane.showInputDialog("보낼 메세지를 입력하세요"));
				dos.flush();
				System.out.println("나 : "+dos);
				System.out.println(sock.getInetAddress()+" : "+dis.readUTF());
			}
			
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
}

File

인자값을 넣어라

import java.io.File;

//File class
public class Exam_01 {
	public static void main(String[] args) {
		//하드디스크의 특정 파일
		File file = new File("d:/연습폴더/jl1.0.1.jar");
		System.out.println("파일 존재 여부 : "+file.exists());
		System.out.println("파일 사이즈 : "+file.length());
		System.out.println("파일인가? : "+file.isFile());
		System.out.println("폴더인가? : "+file.isDirectory());
		System.out.println("파일의 경로 : "+file.getAbsolutePath());
		System.out.println("파일의 이름 : "+file.getName());
		System.out.println("파일의 상위 폴더 : "+file.getParent());
//		file.delete();
		
		File folder = new File("d:/연습폴더");
		File[] files = folder.listFiles();
		
		for(File f: files) { //컬렉션 대상으로는 for-each 문 사용가능
			System.out.println(f.getName()+" : "+f.length());
//			f.delete();
		}
	}
}

결과


파일 목록 읽어오기

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.net.ServerSocket;
import java.net.Socket;

import javax.swing.JOptionPane;

public class Server {
	public static void main(String[] args) {
		String msg = null;
		try {
			ServerSocket server = new ServerSocket(50000);

			System.out.println("서버를 가동했습니다.");
			Socket sock = server.accept();
			System.out.println(sock.getInetAddress() + " 에서 연결");


			DataInputStream dis = 
					new DataInputStream(sock.getInputStream());
			DataOutputStream dos = 
					new DataOutputStream(sock.getOutputStream());

			File root = new File("D:/연습폴더");
			File[] files = root.listFiles();
			
			dos.writeInt(files.length); // filse배열사이즈(개수) 알려주기
			for(File f: files) { //컬렉션이므로 for-each문으로 반복
				dos.writeUTF(f.getName());
				System.out.println(f.getName());
			}

		}catch(Exception e) {
			e.printStackTrace();

		}
	}
}
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class Client {
	public static void main(String[] args) {
		try {

			Socket sock  = new Socket("192.168.60.57", 50000);

			DataInputStream dis = 
					new DataInputStream(sock.getInputStream());
			DataOutputStream dos = 
					new DataOutputStream(sock.getOutputStream());

			int filesLength =dis.readInt(); // int로 읽어오기
			System.out.println("파일 개수 : "+filesLength);

			List<String> list = new ArrayList<>();
			for(int i=0; i<filesLength; i++) {
			list.add(dis.readUTF());
			}
			System.out.println(list);
			
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
}

파일 목록 받고 특정 파일 선택하기

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
	public static void main(String[] args) {
		String msg = null;
		try {
			ServerSocket server = new ServerSocket(50000);

			System.out.println("서버를 가동했습니다.");
			Socket sock = server.accept();
			System.out.println(sock.getInetAddress() + " 에서 연결");


			DataInputStream dis = 
					new DataInputStream(sock.getInputStream());
			DataOutputStream dos = 
					new DataOutputStream(sock.getOutputStream());

			File root = new File("D:/연습폴더");
			File[] files = root.listFiles();
			
			dos.writeInt(files.length); //files배열사이즈(개수) 알려주기
			for(File f: files) { //컬렉션이므로 for-each문으로 반복
				dos.writeUTF(f.getName());
				System.out.println(f.getName());
			}
			
			String fileName = dis.readUTF();
			System.out.println(sock.getInetAddress()+ " 님의 선택 파일 : "+fileName);
			
		}catch(Exception e) {
			e.printStackTrace();

		}
	}
}
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JOptionPane;

public class Client {
	public static void main(String[] args) {
		try {

			Socket sock  = new Socket("192.168.60.57", 50000);

			DataInputStream dis = 
					new DataInputStream(sock.getInputStream());
			DataOutputStream dos = 
					new DataOutputStream(sock.getOutputStream());

			int filesLength =dis.readInt(); // int로 읽어오기
			System.out.println("파일 개수 : "+filesLength);

			List<String> list = new ArrayList<>();
			for(int i=0; i<filesLength; i++) {
			list.add(dis.readUTF());
			}
			System.out.println(list);
			
			dos.writeUTF(JOptionPane.showInputDialog("파일명을 입력하세요"));
			dos.flush();
			
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
}

 


파일 전송

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
	public static void main(String[] args) {
		String msg = null;

		try {
			ServerSocket server = new ServerSocket(50000);

			System.out.println("서버를 가동했습니다.");
			Socket sock = server.accept();
			System.out.println(sock.getInetAddress() + " 에서 연결");



			DataInputStream dis = 
					new DataInputStream(sock.getInputStream());
			DataOutputStream dos = 
					new DataOutputStream(sock.getOutputStream());
			
			while(true) {
				File root = new File("D:/연습폴더");
				root.listFiles();  //파일형 배열이 리턴타입. 폴더안에있는 파일들을 배열에 담음*
				File[] files = root.listFiles();

				dos.writeInt(files.length); //files배열사이즈(개수) 알려주기
				dos.flush();//*

				for(File f: files) { //컬렉션이므로 for-each문으로 반복
					dos.writeUTF(f.getName());
					dos.flush();//*
				}

				String fileName = dis.readUTF();
				System.out.println(sock.getInetAddress()+ " 님의 선택 파일 : "+fileName);
				//여기서 오류?

				File target = new File("d:/연습폴더/"+fileName);

				//파일 스트림 만들기 (하드디스크 내용을 램으로 불러오기, 기준점은 램)
				FileInputStream fis = new FileInputStream(target); // FileInputStream은 빨대
				DataInputStream fileDis = new DataInputStream(fis); // 업그레이드


				//파일 사이즈 보내주기
				dos.writeLong(target.length());
				dos.flush();


				//가져온 파일을 담을 장소 필요, 파일은 이진수이므로 바이트 배열이 적합
				byte[] fileContents = new byte[(int)target.length()];//파일의 사이즈 만큼의 바이트배열 만들기
				//배열을 만들때 사이즈는 int로만 만들 수 있음

				fileDis.readFully(fileContents);//한번에 읽어오기
				//하드디스크 내용을 램으로 불어오는 과정 끝

				dos.write(fileContents);
				dos.flush();
			}
		}catch(Exception e) {
			e.printStackTrace();
		}

	}
}
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.net.Socket;

import javax.swing.JOptionPane;

public class Client {
	public static void main(String[] args) throws Exception{


		Socket sock  = new Socket("192.168.60.19", 50000);//"127.0.0.1" 나혼자할때!

		DataInputStream dis = 
				new DataInputStream(sock.getInputStream());
		DataOutputStream dos = 
				new DataOutputStream(sock.getOutputStream());


		int filesLength =dis.readInt(); // int로 읽어오기
		System.out.println("파일 개수 : "+filesLength);


		for(int i=0; i<filesLength; i++) {
			System.out.println(dis.readUTF());
		}


		dos.writeUTF(JOptionPane.showInputDialog("서버로부터 받을 파일명을 입력하세요"));
		dos.flush();

		//파일을 받으려면 바이트배열 생성, 바이트배열 만들려면 파일사이즈 알아야
		long fileSize = dis.readLong();
		System.out.println("파일 사이즈 : "+fileSize);

		byte[] fileContents = new byte[(int)fileSize];

		dis.readFully(fileContents);//여기부터 오류

		FileOutputStream fos = new FileOutputStream("d:/연습폴더/전송완료.txt"); //저장할 위치
		DataOutputStream fileDos = new DataOutputStream(fos);

		fileDos.write(fileContents);
		fileDos.flush();
		fileDos.close();


	}
}

*서버측에서 도중에 연결 끊기지 않도록 while문 사용

*데이터 보내줄 때마다 잊지말고 .flush()


병행처리 : 쓰레드

  • Thread - 컴퓨터 내에서 일을 처리하는 단위
    범용성문법, 운영체제에 의해 관리되는 일의 단위
    싱글 스레드 프로세스
    하나의 프로세스 안에 여러개의 스레드 : 멀티 스레드 프로세스
    운영 체제의 스케쥴링 알고리즘 우선순위에 따라 스레드에 배정하는 시간 달라짐


Java에서 Thread를 구현하는 5-Step

  1. Thread 클래스를 상속받는 사용자 정의 클래스를 생성한다.
  2. Thread 클래스로부터 상속받은 public void run 메서드를 오버라이딩 한다.
  3. public void run 메서드 내에 병행처리 할 코드를 작성한다.
  4. 작성된 사용자 정의 클래스를 바탕으로 인스턴스를 생성한다.
  5. 생성된 인스턴스로부터 start() 메서드를 호출한다.

class Worker extends Thread{ // 오버라이딩 등을 하라는 에러 없음 > 추상메서드를 포함하지 않음
	//디폴트 컨스트럭터안에 super();> 인자값이 없음 > 인자를 갖지 않는 생성자 존재

	public void run() {// 초록색 화살표, 오버라이딩 되었다.
		for(int i =0; i<=10; i++) {
			System.out.println(i);
		}
	}
}


public class Exam_02 {
	public static void main(String[] args) {
		// Thread - 컴퓨터 내에서 일을 처리하는 단위
		// 범용성문법, 운영체제에 의해 관리되는 일의 단위
		// 싱글 스레드 프로세스
		// 하나의 프로세스 안에 여러개의 스레드 : 멀티 스레드 프로세스
		// 운영 체제의 스케쥴링 알고리즘 우선순위에 따라 스레드에 배정하는 시간 달라짐

		Worker w = new Worker();
		w.start(); //start와 동시에 스레드 추가, 싱글스레드로 시작했다가

		for(int i =0; i<=10; i++) {
			System.out.println(i);
		}
	}
}