카테고리 없음

2024. 7. 18. (목) 슈퍼코딩 부트캠프 Day 40 / 주특기 4주차

태영9922 2024. 7. 18. 18:13

 

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();
    }

}