통신(반이중, 전이중)

#반이중 #전이중 #SOLID #객체 지향 설계의 5원칙
hyeonn's avatar
Jan 10, 2024
통신(반이중, 전이중)

객체 지향 설계의 5원칙 (SOLID)

SRP(Single Responsibility Principle): 단일 책임 원칙 → 하나의 클래스는 하나의 기능 담당
OCP(Open Closed Priciple): 개방 폐쇄 원칙 → 확장에 개방, 수정에 폐쇄, 추상화 사용
LSP(Listov Substitution Priciple): 리스코프 치환 원칙 → 서브 타입은 부모 타입으로 교체 O (다형성)
ISP(Interface Segregation Principle): 인터페이스 분리 원칙 → 인터페이스의 단일 책임
DIP(Dependency Inversion Principle): 의존 역전 원칙 → 대상의 상위 요소 (추상클래스, 인터페이스)로 참조 → 구현 클래스 의존 X, 인테페이스에 의존

반이중

  • 양방향 전송이 가능하지만 동시에 양쪽 방향에서 전송할 수 없는 방식
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.nio.charset.Charset; public class Server { public static void main(String[] args) { try { ServerSocket serverSocket = new ServerSocket(2000); Socket socket = serverSocket.accept(); // 소켓 연결 완료 // 버퍼 만들기 (received) BufferedReader br = new BufferedReader( new InputStreamReader(socket.getInputStream()) ); String requestMsg = br.readLine(); System.out.println("클라이언트로부터 받은 메세지: " + requestMsg); //버퍼 만들기 (send) PrintWriter pw = new PrintWriter(socket.getOutputStream(), true, Charset.forName("UTF-8")); if (requestMsg.equals("1")) { pw.println("영화"); } else if (requestMsg.equals("2")) { pw.println("드라마"); } else { pw.println("프로토콜을 확인하세요 -> 1은 영화, 2는 드라마"); } } catch (IOException e) { throw new RuntimeException(e); } } }
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; public class Client { public static void main(String[] args) { try { Socket socket = new Socket("localhost", 2000); PrintWriter pw = new PrintWriter(socket.getOutputStream(), true); pw.println("1"); BufferedReader br = new BufferedReader( new InputStreamReader(socket.getInputStream()) ); String responseMsg = br.readLine(); System.out.println("서버로부터 받은 메세지: " + responseMsg); } catch (IOException e) { throw new RuntimeException(e); } } }
 

전이중

IP주소 확인 방법 → ipconfig
IP주소 확인 방법 → ipconfig
  • 동시에 양방향 전송이 가능한 방식
서버는 키보드를 읽어야 하며 BW와 Br이 하나의 스레드로 묶어서 동기화해서 사용
서버는 키보드를 읽어야 하며 BW와 Br이 하나의 스레드로 묶어서 동기화해서 사용
  1. 서버 생성
  1. 클라이언트 생성
  1. 클라이언트 → 서버 (메세지를 지속적으로 전송)
  1. 서버 → 클라이언트 (메세지를 지속적으로 전송)
내가 만든 전이중 채팅
내가 만든 전이중 채팅
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; public class Server { public static void main(String[] args) { Scanner sc = new Scanner(System.in); try { ServerSocket serverSocket = new ServerSocket(5000); Socket socket = serverSocket.accept(); PrintWriter pw = new PrintWriter(socket.getOutputStream(), true); BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); System.out.println("클라이언트와 연결 완료"); Thread receiveThread = new Thread(() -> { String requestMsg; try { while ((requestMsg = br.readLine()) != null) { System.out.println("-클라이언트로부터 받은 메세지: " + requestMsg); if (requestMsg.equalsIgnoreCase("quit")) { System.out.println("연결 종료"); break; } } } catch (IOException e) { throw new RuntimeException(e); } }); Thread sendThread = new Thread(() -> { String sendMsg; while (true) { System.out.print("클라이언트로 보낼 메세지 입력 후 엔터: "); sendMsg = sc.nextLine(); pw.println(sendMsg); } }); receiveThread.start(); sendThread.start(); receiveThread.join(); sendThread.join(); } catch (IOException | InterruptedException e) { throw new RuntimeException(e); } } }
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.util.Scanner; public class Client { public static void main(String[] args) { final Scanner sc = new Scanner(System.in); try { Socket clientSocket = new Socket("localhost", 5000); BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); PrintWriter pw = new PrintWriter(clientSocket.getOutputStream(), true); Thread sendThread = new Thread(() -> { String responseMsg; while (true) { System.out.print("서버로 보낼 메세지 입력 후 엔터: "); responseMsg = sc.nextLine(); pw.println(responseMsg); if (responseMsg.equalsIgnoreCase("quit")) { break; } } }); Thread receiveThread = new Thread(() -> { String receiveMsg; try { while ((receiveMsg = br.readLine()) != null) { System.out.println("-서버로부터 온 메세지: " + receiveMsg); } } catch (IOException e) { throw new RuntimeException(e); } }); sendThread.start(); receiveThread.start(); sendThread.join(); receiveThread.join(); } catch (IOException | InterruptedException e) { throw new RuntimeException(e); } } }
 
풀이
풀이
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; public class Server { public static void main(String[] args) { try { // 1. 소켓과 버퍼 만들기 ServerSocket serverSocket = new ServerSocket(2000); Socket socket = serverSocket.accept(); PrintWriter pw = new PrintWriter(socket.getOutputStream(), true); Scanner sc = new Scanner(System.in); BufferedReader br = new BufferedReader( new InputStreamReader(socket.getInputStream()) ); // 2. 메세지 받기 스레드, 다른 스택이라 try-catch 가능 new Thread(() -> { while (true) { try { String requestMsg = br.readLine(); System.out.println("클라이언트로부터 받은 메세지: " + requestMsg); } catch (IOException e) { e.printStackTrace(); } } }).start(); new Thread(() -> { while (true) { String keyboardMsg = sc.nextLine(); pw.println(keyboardMsg); } }).start(); } catch (IOException e) { throw new RuntimeException(e); } } }
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.util.Scanner; public class Client { public static void main(String[] args) { try { // 1. 소켓과 버퍼 만들기 Socket socket = new Socket("localhost", 2000); PrintWriter pw = new PrintWriter(socket.getOutputStream(), true); Scanner sc = new Scanner(System.in); BufferedReader br = new BufferedReader( new InputStreamReader(socket.getInputStream()) ); // 2. 메세지 전송 스레드 new Thread(() -> { while (true) { String keyboardMsg = sc.nextLine(); pw.println(keyboardMsg); } }).start(); //3. 메세지 읽기 스레드 new Thread(() -> { while (true) { try { String requestMsg = br.readLine(); System.out.println("클라이언트로부터 받은 메세지: " + requestMsg); } catch (IOException e) { e.printStackTrace(); } } }).start(); } catch (IOException e) { throw new RuntimeException(e); } } }
전이중 → state full - 최초의 소켓 연결 후 요청과 응답이 끊기지 않는 거
반이중 → state less - 응답이 끊기는 거
Share article

from-web-developer