[24.09.07] TIL

yy·2024년 9월 5일

개발일지

목록 보기
96/122

인터페이스

클래스와 달리 객체를 생성 불가. 클래스에서 구현해야하는 작업 명세서.

클래스 - (구현) - > 인터페이스

무엇을 구현?

인터페이스 기능(선언만 되어있고, 껍질만 가지고 있음)을 클래스에서 구현.

메소드를 선언만 하고, 정의( {}부 )는 하지 않음. 정의는 클래스에서 함.

가장 큰 이유는 객체가 다양한 자료형(타입)을 가질 수 있기때문.

implements 를 이용해서 인터페이스를 여러개 넣을 수 있음.

인터페이스를 이용하면 객체가 다양한 자료형(타입)을 가질 수 있음.

예시 1)

package pjTest;

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

		InterfaceA ia = new InterfaceClass();
		InterfaceB ib = new InterfaceClass();
		
		ia.funcA();
		ib.funcB();
	}
}
package pjTest;

public class InterfaceClass implements InterfaceA, InterfaceB {
	public InterfaceClass() {
		System.out.println("--InterfaceClass countructor--");
	}

	@Override
	public void funcA() {
		System.out.println("--funcA--");
	}
	
	@Override
	public void funcB() {
		System.out.println("--funcB--");
		
	}
}
package pjTest;

public interface InterfaceA {
	public void funcA();
}
package pjTest;

public interface InterfaceB {
	public void funcB();
}


예시 2)

package pjTest;

public class MainClass {
	public static void main(String[] args) {
		Toy ta = new ToyAirplane();
		Toy tr = new ToyRobot();
		
		Toy[] toys = { ta, tr };
		
		for(int i =0; i<toys.length; i++) {
			toys[i].walk();
			toys[i].run();
			toys[i].alarm();
			toys[i].light();
		}
	}
}
package pjTest;

public interface Toy {
	
	public void walk();
	public void run();
	public void alarm();
	public void light();
}
package pjTest;

public class ToyAirplane implements Toy{
	public ToyAirplane() {
		System.out.println("--ToyAirplane constructor--");
	}

	@Override
	public void walk() {
		System.out.println("비행기는 걷지 못함");
	}

	@Override
	public void run() {
		System.out.println("비행기는 뛰지 못함");
	}

	@Override
	public void alarm() {
		System.out.println("비행기는 알람 기능 있음");		
	}

	@Override
	public void light() {
		System.out.println("비행기는 라이트 기능 있음");				
	}
}
package pjTest;

public class ToyRobot implements Toy {
	public ToyRobot() {
		System.out.println("--ToyRobot constructor--");
	}

	@Override
	public void walk() {
		System.out.println("로봇은 걸을 수 있음");
	}

	@Override
	public void run() {
		System.out.println("로봇은 뛸 수 있음");
	}

	@Override
	public void alarm() {
		System.out.println("로봇은 알람 기능 없음");
	}

	@Override
	public void light() {
		System.out.println("로봇은 라이트 기능 있음");
	
	}
}
// 출력값
--ToyAirplane constructor--
--ToyRobot constructor--
비행기는 걷지 못함
비행기는 뛰지 못함
비행기는 알람 기능 있음
비행기는 라이트 기능 있음
로봇은 걸을 수 있음
로봇은 뛸 수 있음
로봇은 알람 기능 없음
로봇은 라이트 기능 있음


추상클래스

클래스의 공통된 부분을 뽑아서 별도의 클래스(추상클래스)로 만들어놓고, 이것을 상속해서 사용.

추상클래스는 공통부분을 추상적으로 만들어놓고, 나머지는 상속받은 클래스에서 알아서 만들어서 사용할 수 있도록 만든 클래스.

추상클래스 특징

  • 멤버변수를 가짐.

  • 상속하기 위해서는 extends 이용

  • 정의부가 없는 메소드를 가지며(인터페이스처럼), 상속한 클래스에서 반드시 구현해야함.

  • 일반 메소드도 가질 수 있음 (정의부가 있는 메소드)

  • 일반 클래스와 마찬가지로 생성자 있음

  • 정의부가 없는 메소드는 상속받은 클래스에서 반드시 구현해야함.


예시 1)

package pjTest;

public class MainClass {
	public static void main(String[] args) {
		AbstractClassEx ab = new ClassEx(10, "java");
		
		ab.fun1();
		ab.fun2();
	}
}
package pjTest;

public abstract class AbstractClassEx {
	int num;
	String str;
	
	public AbstractClassEx() {
		System.out.println("--AbstractClassEx Counstructor--");
	}
	
	public AbstractClassEx(int i, String s) {
		System.out.println("--AbstractClassEx Counstructor--");
		
		this.num = i;
		this.str = s;
	}
	
	public void fun1() {
		System.out.println("-- fund1() START --");
	}
	
	public abstract void fun2();
}
package pjTest;

public class ClassEx extends AbstractClassEx{

	public ClassEx() {
		System.out.println("--ClassEx Constructor1--");
	}
	
	public ClassEx(int i, String s) {
		super(i, s);
	}
	
	@Override
	public void fun2() {
		System.out.println("-- fund2() START(ClassEx) --");
	}

}


예시 2)

package pjTest;

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

		Bank mybank = new Mybank("홍길동", "123-456", 100);
		
		mybank.deposit();
		mybank.withdraw();
		mybank.installmentSavings();
		mybank.cancellation();
	}
}
package pjTest;

public abstract class Bank {
	String name;
	String account;
	int totalAmount;
	
	public Bank() {
		System.out.println("--Bank Constructor 1--");
	}
	
	public Bank(String n, String a, int ta) {
		System.out.println("--Bank Constructor 2--");
		
		this.name = n;
		this.account = a;
		this.totalAmount = ta;
	}
	
	//예금
	public void deposit() {
		System.out.println("(Bank) deposit");
	}
	
	//출금
	public void withdraw() {
		System.out.println("(Bank) withdraw");
	}
	
	//적금
	public abstract void installmentSavings();
	
	//해지
	public abstract void cancellation();
	
	//정보출력
	public void getInfo() {
		System.out.printf("name : $s\n", name);
		System.out.printf("account : $s\n", account);
		System.out.printf("totalAmount : $d\n", totalAmount);
	}
}
package pjTest;

public class Mybank extends Bank {

	public Mybank() {
		System.out.println("--Mybank Constructor 1--");
	}
	
	public Mybank(String n, String a, int ta) {
		super(n, a, ta);
	}
	
	@Override
	public void installmentSavings() {
		System.out.println("(MyBank) installmentSavings");
		
	}

	@Override
	public void cancellation() {
		System.out.println("(MyBank) cancellation");
	}
}
//결과
--Bank Constructor 2--
(Bank) deposit
(Bank) withdraw
(MyBank) installmentSavings
(MyBank) cancellation


interface, abstract class의 공통점, 차이점

공통점

추상 메소드를 가짐. 객체 생성이 불가하며 자료형(타입)으로 사용됨.

차이점

interface : 상수, 추상 메소드만 가짐. 추상 메소드를 구현만 하도록하며 다형성을 지원(implements를 이용하기 때문 다형성 지원)

abstract class : 클래스가 가지는 모든 속성과 기능을 가짐. 추상 메소드 구현 및 상속의 기능을 가짐. 단일 상속만 지원.(extends를 이용한 상속이기때문에 단일상속)



람다식

익명함수를 이용해서 익명 객체를 생성하기 위한 식.

기존 방법 : 인터페이스를 구현 후 인터페이스 타입 변수에 할당(대입)하여 사용.

  • 인터페이스 -> 클래스 작성 -> main클래스에서 호출

람다식 방법: 람다식을 인터페이스 타입 변수에 할당(대입)하여 사용.

  • 인터페이스 -> main 클래스 호출(화살표함수처럼...)

  • 인터페이스에 메소드를 선언만해주고, main클래스에서 화살표를 이용하여 일시적으로 정의함.

package pjTest;

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

		// 매개변수와 실행문만으로 작성한다.(접근자, 반환형, return 키워드 생략)
		LambdaInterface1 li1 = (String s1, String s2, String s3) ->
		{ System.out.println(s1 + " " + s2 + " " + s3); };
		li1.method("Hello", "java", "World");
		System.out.println();
        
		// 매개변수가 1개이거나 타입이 같을 때, 타입을 생략할 수 있다.
		LambdaInterface2 li2 = (s1) -> { System.out.println(s1); };
		li2.method("Hello");
        
		// 실행문이 1개일 때, '{}'를 생략할 수 있다.
		LambdaInterface2 li3 = (s1) -> System.out.println(s1);
		li3.method("Hello");
        
		// 매개변수와 실행문이 1개일 때, '()'와 '{}'를 생략할 수 있다.
		LambdaInterface2 li4 = s1 -> System.out.println(s1);
		li4.method("Hello");
        
		// 매개변수가 없을때, '()'만 작성한다.
		LambdaInterface3 li5 = () -> System.out.println("no parameter");
		li5.method();
		
		// 반환값이 있는 경우
		LambdaInterface4 li6 = (x, y) -> {
			int result = x + y;
			return result;
		};
		System.out.printf("li6.method(10, 20) : %d\n", li6.method(10, 20));
		li6 = (x, y) -> {
			int result = x * y;
			return result;
		};
		System.out.printf("li6.method(10, 20) : %d\n", li6.method(10, 20));
		li6 = (x, y) -> {
			int result = x - y;
			return result;
		};
		System.out.printf("li6.method(10, 20) : %d\n", li6.method(10, 20));
	}
}
package pjTest;

public interface LambdaInterface1 {
	public void method(String s1, String s2, String s3);
}
package pjTest;

public interface LambdaInterface2 {
	public void method(String s1);
}
package pjTest;

public interface LambdaInterface3 {
	public void method();
}
package pjTest;

public interface LambdaInterface4 {
	public int method(int x, int y);
}


문자열 클래스

기본자료형이 아님. 객체임. String str = new String("java"); 이렇게 써야하지만 많이 사용하니까 기본 자료형 처럼 사용할 수 있도록 만든거임. String str = "java"

문자열을 다루는 string 클래스(객체)는 데이터가 변하면 메모상변화가 많아 속도가 느림.

문자열이 변경되면 기존객체를 재활용하는 것이 아니라 기존의 객체를 버리고, 새로운 객체를 메모리에 생성한다. 이때 기존 객체는 GC에 의해서 메모리 회수가 이루어진다.

String buffer, StringBuilder

String클래스의 단점을 보완한(String 변경 시 속도 저하) 클래스로 데이터가 변경되면 메모리에서 기존 객체를 재활용.

문자열이 변경되면 기존의 객체를 재활용.

속도는 StringBuilder가 조금 더 빠르며 데이터 안정성은 StringBuffer가 조금 더 좋다.

//StringBuffer
StringBuffer sf = new StringBuffer("JAVA");

sf.append("_8");
sf.insert(1, "---"); // 원하는 인덱스에 문자열 추가
sf.delete(1, 3); //원하는 범위만큼 삭제

//StringBuilder
StringBuilder sd = new StringBuilder("JAVA");


Collections

List

  • 인터페이스로 구현한 클래스. 인덱스를 이용해서 데이터를 관리.

  • Vector, ArrayList, LinkedList 클래스

Map

  • 인터페이스로 구현한 클래스. key를 이용해서 데이터 관리.

  • key를 이용.

  • key 중복 안되지만, 데이터 중복은 가능.

package pjTest;

import java.util.ArrayList;
import java.util.HashMap;

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

		// ArrayList 객체 생성
		ArrayList<String> list = new ArrayList<String>();
		
		System.out.println("list.size : " + list.size());
		
		// 데이터 추가
		list.add("Hello");
		list.add("Java");
		list.add("World");
		System.out.println("list.size : " + list.size());
		System.out.println("list : " + list);
		
		list.add(2, "Programing");	// 추가
		System.out.println("list : " + list);
		
		list.set(1, "C");			// 변경
		System.out.println("list : " + list);
		
		// 데이터 추출
		String str = list.get(2);
		System.out.println("list.get(2) : " + str);
		System.out.println("list : " + list);
		
		// 데이터 제거
		str = list.remove(2);
		System.out.println("list.remove(2) : " + str);
		System.out.println("list : " + list);
		
		// 데이터 전체 제거
		list.clear();
		System.out.println("list : " + list);
		
		// 데이터 유무
		boolean b = list.isEmpty();
		System.out.println("list.isEmpty() : " + b);
		
		System.out.println(" ==================================== ");
		
		// HashMap 객체 생성
		HashMap<Integer, String> map = new HashMap<Integer, String>();
		System.out.println("map.size() : " + map.size());
		
		// 데이터 추가
		map.put(5, "Hello");
		map.put(6, "Java");
		map.put(7, "World");
		System.out.println("map : " + map);
		System.out.println("map.size() : " + map.size());
		
		map.put(8, "!!");
		System.out.println("map : " + map);
		
		// 데이터 교체
		map.put(6, "C");
		System.out.println("map : " + map);
		
		// 데이터 추출
		str = map.get(5);
		System.out.println("map.get(5) : " + str);
		
		// 데이터 제거
		map.remove(8);
		System.out.println("map : " + map);
		
		// 특정 데이터 포함 유무
		b = map.containsKey(7);
		System.out.println("map.containsKey(7) : " + b);
		
		b = map.containsValue("World");
		System.out.println("map.containsValue(\"World\") : " + b);
		
		// 데이터 전체 제거
		map.clear();
		System.out.println("map : " + map);
		
		// 데이터 유무
		b = map.isEmpty();
		System.out.println("map.isEmpty() : " + b);
	}
}


예외처리

프로그램에 문제가 있는 것. 예외로 인해 시스템 동장이 멈추는것을 막는 것을 예외처리라고 함.

  • Exception: 개발자 대처 가능 (소프트웨어상으로 문제가 생긴 것)

  • Checked Exception (예외처리 반드시 해야하는 경우. 네트워크 파일 시스템 등),

  • Unchecked Exception (데이터 오류 등))

  • Error: 개발자 대처 불가능 (하드웨어적으로 문제가 생긴 것)

Exception class

NullPointException : 객체를 가리키지않고 레퍼런스를 이용할 때

ArrayIndexOutOfBoundException : 배열에서 존재하지않는 인덱스를 가리킬 때

NumberFormatException: 숫자 데이터에 문자 데이터 등을 넣었을 때

등등 많은 클래스를 가지고 있음.

try ~ catch ~

try {
	예외가 발생할 수 있는 코드
} catch (Exception e ) {
	예외가 발생했을 때 처리할 코드
}
int i = 10;
int j = 0;
int r = 0;

System.out.println("Ecexption BEFORE");

try {
	r = i / j;
} catch (Exception e) {
	e.printStackTrace();
	String msg = e.getMessage(); //예외 간략 메시지
	System.out.println("Exception: " + msg);
}

System.out.println("Exception AFTER");


finally

  • 예외 발생 여부와 상관없이 반드시 실행.
try {
	...
} catch (InputMismatchException e) {
	...
} catch (ArrayIndexOutOfBoundsException e) {
	...
} catch (Exception e) {
	...
} finally {
	System.out.println("예외 발생 여부에 상관없이 언제나 실행 됩니다.");
}


throws

  • 예외발생 시 예외처리를 직접하지 않고 호출한 곳으로 넘김.

  • main class에서 try문을 실행해서 firstMethod -> secondMethod -> thirdMethod 까지 가서 예외가 발생한 후 호출한 곳으로 돌아와서 다시 main class로 돌아온다. 그 후 catch문으로 들어간다.

MainClass004 mainClass004 = new MainClass004();
try {
	mainClass004.firstMethod();
} catch (Exception e) {
	e.printStackTrace();
public void firstMethod() throws Exception {
	secondMethod();
}
public void secondMethod() throws Exception {
	thirdMethod();
}
public void thirdMethod() throws Exception {
	System.out.println("10 / 0 = " + ( 10 / 0 ));
}


입력과 출력

  • 다른 곳의 데이터를 가져오는 것을 입력. 다른 곳으로 데이터를 내보는 것을 출력.

  • 입출력에 사용되는 기본클래스는 1바이트 단위로 데이터를 전송하는 inputStream, outputstream이 있음

FileInputStream / FileOutputStream

파일에 데이터를 읽고, 쓰기위한 클래스. read(), write() 메소드 이용.

read() : 1byte씩 읽기

read(byte[]) : []배열의 크기씩 읽기

write(byte[] b) : 전체쓰기

write(byte[], int off, int len): off(시작점), len(길이)

// inputStream 입력
// read()
InputStream inputStream = null;
try {
	
	inputStream = new FileInputStream("C:\\java\\pjt_ex\\hello.txt");
	int data = 0;
	
	while(true) {
		
		try {
			data = inputStream.read();
		} catch (IOException e) {
			e.printStackTrace();
		}
		if(data == -1) break;
		System.out.println("data : " + data);
	}
	
} catch (FileNotFoundException e) {
	e.printStackTrace();
} finally {
		try {
			if(inputStream != null) inputStream.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
}
// outputStream 출력
// write()
OutputStream outputStream = null;
try {
	
	outputStream = new FileOutputStream("C:\\java\\pjt_ex\\helloW.txt");
	String data = "Hello java world!!";
	byte[] arr = data.getBytes();
	
	try {
		outputStream.write(arr);
	} catch (IOException e) {
		e.printStackTrace();
	}
	
} catch (FileNotFoundException e) {
	e.printStackTrace();
} finally {
		try {
			if(outputStream != null) outputStream.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
}

파일 복사

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

public class MainClass003 {
	
	public static void main(String[] args) {
		
		InputStream inputStream = null;
		OutputStream outputStream = null;
		
		try {
			inputStream = new FileInputStream("C:\\java\\pjt_ex\\hello.txt");
			outputStream = new FileOutputStream("C:\\java\\pjt_ex\\helloCopy.txt");
			
			byte[] arr = new byte[3];
			
			while(true) {
				int len = inputStream.read(arr);
				if(len == -1) break;
				outputStream.write(arr, 0, len);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (Exception e) { e.printStackTrace(); }
			}
			
			if (outputStream != null) {
				try {
					outputStream.close();
				} catch (Exception e) { e.printStackTrace(); }
			}
		}
	}
}

DataInputStream, DataOutputStream

  • byte단위의 입출력을 개선해서 문자열을 좀 더 편리하게 다룰 수 있음.

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

public class MainClass0041 {
	
	public static void main(String[] args) {
		
		InputStream inputStream = null;
		DataInputStream dataInputStream = null;
		OutputStream outputStream = null;
		DataOutputStream dataOutputStream = null;
		
		try {
			
			inputStream = new FileInputStream("C:\\java\\pjt_ex\\helloWorld.txt");
			dataInputStream = new DataInputStream(inputStream);
			
			String str = dataInputStream.readUTF();
			
			outputStream = new FileOutputStream("C:\\java\\pjt_ex\\helloWorldCopy.txt");
			dataOutputStream = new DataOutputStream(outputStream);
			
			dataOutputStream.writeUTF(str);
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if(dataOutputStream != null) dataOutputStream.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			
			try {
				if(outputStream != null) outputStream.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}

BufferInputStream, BufferOutputStream

  • byte 단위의 입출력을 개선해서 문자열을 좀 더 편리하게 다룰 수 있다.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class MainClass {
	
	public static void main(String[] args) {
		
		String fileName = "C:\\java\\pjt\\helloReader.txt";
		
		BufferedReader br = null;
		FileReader fr = null;

		try {

			fr = new FileReader(fileName);
			br = new BufferedReader(fr);

			String strLine;

			while ((strLine = br.readLine()) != null) {
				System.out.println(strLine);
			}

		} catch (IOException e) {
			e.printStackTrace();
		} finally {

			try {
				if (br != null) br.close();
				if (fr != null) fr.close();
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
	}
}


네트워킹

네트워크 데이터 입력 및 출력

네트워크 대상(객체)사이에 입출력을 이용해서 데이터를 입력하고 출력.

소켓

네트워크상에서 데이터를 주고받기 위한 장치. (전화기)

소켓 클래스

클라이언트에서는 socket을, 서버에서는 serverSocket을 만 있으면 됨.

//서버 소켓 기본 핵심 코드
serverSocket = new ServerSocket(9000);
System.out.println();

socket = serverSocket.accept();
System.out.println("socket: " + socket);
//서버 소켓 코드
import java.net.ServerSocket;
import java.net.Socket;

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

		ServerSocket serverSocket = null;
		Socket socket = null;
		
		try {
			serverSocket = new ServerSocket(9000); //port number : 9000
			System.out.println("클라이언트 맞을 준비 완료");			

			socket = serverSocket.accept();
			System.out.println("socket: " + socket);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if(socket != null) socket.close();
				if(serverSocket != null) serverSocket.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		

	}
}

//클라이언트 소켓 코드
import java.net.Socket;

public class MainClassSocket {
	public static void main(String[] args) {
		Socket socket = null;
		
		try {
			socket = new Socket("localhost", 9000);
			System.out.println("서버 연결");
			System.out.println("socket: " + socket);

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if(socket != null) socket.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}

양방향통신

클라이언트와 서버는 inputStream, outputStream을 이용해서 양방향 통신 가능.

// 클라이언트 코드(소켓, I/O)
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;

public class ClientClass {
	
	public static void main(String[] args) {
		
		Socket socket = null;
		
		OutputStream outputStream = null;
		DataOutputStream dataOutputStream = null;
		
		InputStream inputStream = null;
		DataInputStream dataInputStream = null;
		
		Scanner scanner = null;
		
		try {
			
			socket = new Socket("localhost", 9000);
			System.out.println("서버 연결 완료~~");
			
			outputStream = socket.getOutputStream();
			dataOutputStream = new DataOutputStream(outputStream);
			
			inputStream = socket.getInputStream();
			dataInputStream = new DataInputStream(inputStream);
			
			scanner = new Scanner(System.in);
			
			while (true) {
				System.out.println("메시지 입력~~");
				String outMessage = scanner.nextLine();
				dataOutputStream.writeUTF(outMessage);
				dataOutputStream.flush();
				
				String inMessage = dataInputStream.readUTF();
				System.out.println("inMessage : " + inMessage);
				
				if(outMessage.equals("STOP")) break;
				
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				
				if(dataOutputStream != null) dataOutputStream.close();
				if(outputStream != null) outputStream.close();
				if(dataInputStream != null) dataInputStream.close();
				if(inputStream != null) inputStream.close();
				
				if(socket != null) socket.close();
				
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}
// 서버 코드(소켓, I/O)
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerClass {

	public static void main(String[] args) {
		
		ServerSocket serverSocket = null;
		Socket socket = null;
		
		InputStream inputStream = null;
		DataInputStream dataInputStream = null;
		
		OutputStream outputStream = null;
		DataOutputStream dataOutputStream = null;
		
		try {
			
			serverSocket = new ServerSocket(9000);
			System.out.println("클라이언트 맞을 준비 완료~~");
			
			socket = serverSocket.accept();
			System.out.println("클라이언트 연결~~");
			System.out.println("socket: " + socket);
			
			inputStream = socket.getInputStream();
			dataInputStream = new DataInputStream(inputStream);
			
			outputStream = socket.getOutputStream();
			dataOutputStream = new DataOutputStream(outputStream);
			
			while (true) {
				String clientMessage = dataInputStream.readUTF();
				System.out.println("clientMessage : " + clientMessage);
				
				dataOutputStream.writeUTF("메시지 전송 완료~~");
				dataOutputStream.flush();
				
				if(clientMessage.equals("STOP")) break;
			}
			
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				
				if(dataInputStream != null) dataInputStream.close();
				if(inputStream != null) inputStream.close();
				if(dataOutputStream != null) dataOutputStream.close();
				if(outputStream != null) outputStream.close();
				
				if(socket != null) socket.close();
				
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}
profile
시간이 걸릴 뿐 내가 못할 건 없다.

0개의 댓글