1. 네트워크와 소켓프로그래밍
2. Java 소켓 프로그래밍 구현
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(1234);//TODO : 서버 소켓 생성
Socket clientSocket = serverSocket.accept() //TODO : 클라이언트 접속 대기
) {
System.out.println("Server Started");
System.out.println("Client connected");
//TODO : 데이터를 받기 위한 InputStream 생성
InputStream clientInputStream = clientSocket.getInputStream(); //클라이언트로부터 받아온 스트림
BufferedReader clientBufferedReader = new BufferedReader(new InputStreamReader(clientInputStream));
//TODO : 데이터를 보내기위한 OutputStream 생성
OutputStream serverOutputStream = clientSocket.getOutputStream();
PrintWriter printWriter = new PrintWriter(serverOutputStream, true);
String inputLine;
//TODO : 클라이언트로부터 데이터를 읽고 출력
while ((inputLine = clientBufferedReader.readLine()) != null) {
System.out.println("request from client : " + inputLine);
//TODO : 클라이언트에게 응답을 보냄
printWriter.println("this is response from server");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void main(String[] args) {
//TODO : 서버에 연결
try (Socket socket = new Socket("localhost", 1234)) {
//TODO : 서버로 데이터를 보내기 위한 OutputStream 생성
OutputStream outputStream = socket.getOutputStream();
PrintWriter clientPrintWriter = new PrintWriter(outputStream, true);
//TODO : 서버로부터 데이터를 받기 위한 InputStream 생성
InputStream inputStream = socket.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
//TODO : 서버에 메시지 전송
clientPrintWriter.println("this is request from client");
//TODO : 서버로부터 받은 응답 출력
String response = bufferedReader.readLine();
System.out.println("response from server : " + response);
System.out.println("client 종료");
} catch (UnknownHostException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
3. Java 데이터 직렬화 / 역직렬화
- 직렬화 : Java 객체 -> Byte 코드
- 역직렬화 : Byte코드 -> Java 객체
import java.io.*;
public class SerializeExampleTest {
public static void main(String[] args) {
//직렬화
Person person = new Person("이순신", "Male", 30, "Korea", "장수");
byte[] serializeData = null; //직렬화 데이터 담을 변수
try (ByteArrayOutputStream bao = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bao)
) {
oos.writeObject(person);
oos.flush();
serializeData = bao.toByteArray();
System.out.println("직렬화 후 : " + new String(serializeData));
} catch (IOException e) {
throw new RuntimeException(e);
}
//역직렬화
try (ByteArrayInputStream bio = new ByteArrayInputStream(serializeData);
ObjectInputStream ois = new ObjectInputStream(bio)
) {
Person person1 = (Person) ois.readObject();
System.out.println("역직렬화 후 : " + person1);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
package exercise.chapter_57;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class ServerAdvance {
public static void main(String[] args) {
List<Customer> customerList = new ArrayList<>();
try (ServerSocket serverSocket = new ServerSocket(1234))//TODO : 서버 소켓 생성
{
System.out.println("Server Started");
while (true) {
try (Socket clientSocket = serverSocket.accept()) {//TODO : 클라이언트 접속 대기
System.out.println("Client connected");
//TODO : 데이터를 받기 위한 InputStream 생성
InputStream clientInputStream = clientSocket.getInputStream(); //클라이언트로부터 받아온 스트림
ObjectInputStream ois = new ObjectInputStream(clientInputStream); //클라이언트에서 받아온 스트림을 Object로 읽기 위한 준비
//TODO : 데이터를 보내기위한 OutputStream 생성
OutputStream serverOutputStream = clientSocket.getOutputStream();
PrintWriter printWriter = new PrintWriter(serverOutputStream, true);
Customer customer = (Customer) ois.readObject(); //클라이언트에서 보낸 Customer 객체를 새로운 객체로 생성
customerList.add(customer);
System.out.println(customer + "가 대기명단에 추가되었음");
//TODO : 클라이언트에게 응답을 보냄
printWriter.println("현재 고객대기명단은 " + customerList);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package exercise.chapter_57;
import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void main(String[] args) {
//TODO : 서버에 연결
try (Socket socket = new Socket("localhost", 1234)) {
//TODO : 서버로 데이터를 보내기 위한 OutputStream 생성
OutputStream outputStream = socket.getOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
//서버로 object를 보내기 위한 스트림 생성
//TODO : 서버로부터 데이터를 받기 위한 InputStream 생성
InputStream inputStream = socket.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
Customer customer = new Customer("ID113", "아이유");
//TODO : 서버에 메시지 전송
objectOutputStream.writeObject(customer); //새로 만든 객체를 서버에 보냄
objectOutputStream.flush();
//TODO : 서버로부터 받은 응답 출력
String response = bufferedReader.readLine();
System.out.println("고객 대기 리스트 : " + response);
System.out.println("client 종료");
} catch (UnknownHostException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
1. Java 메소드 레퍼런스
- Class::MethodName 으로 사용
- 메소드를 참조, 해당 메소드의 동작을 다른 코드에서 재사용할 수 있는 기능
- 자주 사용되는 함수형 인터페이스 (Functional Interface)
함수형 인터페이스
|
파라미터 타입
|
반환 타입
|
추상메소드이름
|
설명
|
Supplier
|
없음
|
T
|
get
|
T타입 값을 공급한다
|
Consumer
|
T
|
void
|
accept
|
T타입 값을 소비한다
|
Function<T, R>
|
T
|
R
|
apply
|
T타입 인자를 받는 함수이다
|
BiFunction<T, U, R>
|
T, U
|
R
|
apply
|
T와 U타입 인자를 받는 함수이다
|
Predicate
|
T
|
boolean
|
test
|
Boolean값을 반환하는 함수이다
|
- 메소드 참조하는 방법
- static method : Class::staticMethod
- 생성자 참조 : Class::new
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
public class MethodReferenceTest1 {
public static void main(String[] args) {
//static method 참조
Consumer<String> ex1 = (str) -> Printer.printSomething(str); //기존 람다식
Consumer<String> ex2 = Printer::printSomething; //메소드 레퍼런스
ex1.accept("lambda식 사용");
ex2.accept("method reference 사용");
//생성자 호출
Supplier<Customer> ex3 = () -> new Customer();
Supplier<Customer> ex4 = Customer::new; //빈 생성자만 호출
System.out.println(ex3.get());
System.out.println(ex4.get());
Function<String, Customer> ex5 = (str) -> new Customer(str);
Function<String, Customer> ex6 = Customer::new;
System.out.println(ex5.apply("이순신"));
System.out.println(ex6.apply("아이유"));
}
}
- 객체 인스턴스 참조 : instance::method (인스턴스화 한 이후에 참조)
- 임의 인스턴스 메소드 참조 : Class::method
import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;
public class MethodReferenceTest2 {
public static void main(String[] args) {
//Instance method 참조
Customer customer1 = new Customer("이순신");
Customer customer2 = new Customer("아이유");
Supplier<String> ex1 = customer1::toString;
Supplier<String> ex2 = customer2::toString;
System.out.println(ex1.get());
System.out.println(ex2.get());
//임의 객체 메소드 호출
List<Customer> customers = Arrays.asList(
new Customer("이순신"),
new Customer("아이유"),
new Customer("카리나"),
new Customer("유재석")
);
customers.forEach(Customer::printMyInfo);
}
}
2. Java Stream에서 메소드 레퍼런스 적용
- static method 참조
- 생성자 참조
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class StreamExample1 {
public static void main(String[] args) {
List<Customer> customers = new ArrayList<>();
customers.add(new Customer("C001", "이순신"));
customers.add(new Customer("C002", "아이유"));
customers.add(new Customer("C003", "카리나"));
customers.add(new Customer("C004", "윈터"));
//StringUtil을 사용하여 해당되는 손님 출력
customers.stream()
.map(Customer::getName) //customers에서 getname으로 string가져와서 map생성
//map(customer -> customer.name) //기존 람다식
.filter(StringUtils::isLongName) //StringUtils에 map의 요소 하나씩 가져옴, filter 적용
.forEach(System.out::println); //각 요소 프린트
//forEach(name -> System.out.println(name))
//이름으로 새로운 customer list를 만들기
List<String> customerNames = Arrays.asList(
"이순신",
"민지",
"오해원",
"아이유"
);
List<Customer> customerList = customerNames.stream()
//.map(name -> new Customer(name))
.map(Customer::new) //customerName리스트에서 각 요소들로 매개변수 하나인 생성자 호출
.collect(Collectors.toList()); //만들어진 객체들로 list 생성하여 반환
System.out.println(customerList);
}
}
- 객체 인스턴스 메소드 참조
- 임의 인스턴스 메소드 참조
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class StreamExample2 {
public static void main(String[] args) {
List<Customer> customers = new ArrayList<>();
customers.add(new Customer("C001", "이순신"));
customers.add(new Customer("C002", "아이유"));
customers.add(new Customer("C001", "이순신"));
customers.add(new Customer("C002", "아이유"));
customers.add(new Customer("C003", "카리나"));
customers.add(new Customer("C001", "이순신"));
customers.add(new Customer("C003", "카리나"));
customers.add(new Customer("C004", "윈터"));
Customer myCustomer = new Customer("C001", "이순신");
//myCustomer와 동일한 객체는 몇개인지 구하기
long count = customers.stream()
.filter(myCustomer::equals)
.count();
System.out.println(count);
//customers의 각각의 bonuspoint 구하기
List<Integer> bonusPoints = customers.stream()
.map(Customer::getBonusPoint)
.collect(Collectors.toList());
System.out.println(bonusPoints);
}
}
1.Thread란? Java의 Thread란?
- Thread는 프로세스 안에서 동시에 진행되는 작업의 갈래
- 왜 사용하는가? Thread가 없으면 순차적으로 작업이 진행되어야 하는데 Thread가 있으면 여러 Thread가 동시에 작업을 처리할 수 있음
- Java는 main 스레드 시작 -> 스레스 객체 생성 -> 실행대기 Runnable <-> 실행 -> 종료 Terminated
- Runnable 함수형 인터페이스 사용
- Runnable 상속받은 클래스 구현 및 사용
public class JavaThreading {
public static void main(String[] args) {
Thread thread1 = new Thread(new MyRunnable());
Thread thread2 = new Thread(new MyRunnable());
Thread thread3 = new Thread(new Runnable() { //익명 클래스
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " 실행 중!");
}
});
Thread thread4 = new Thread(() -> System.out.println(Thread.currentThread().getName() + " 실행 중!"));
//람다식
System.out.println(Thread.currentThread().getName() + " 실행 중!");
thread1.start();
thread2.start();
thread3.start();
thread4.start();
System.out.println(Thread.currentThread().getName() + " 실행 중!");
}
static class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " 실행 중!");
}
}
}
2. Java Multi Thread 프로그래밍
package exercise.chapter_59;
public class MultiThreadingExample {
public static void main(String[] args) {
Thread th1 = new Thread(new PrintNumberRunnable(1, 33));
Thread th2 = new Thread(new PrintNumberRunnable(34, 67));
Thread th3 = new Thread(new PrintNumberRunnable(68, 100));
th1.start();
th2.start();
th3.start();
}
}