- [Java] 98. 코드 리팩토링(1:1 양방향 통신-클라이언트 측)2024년 05월 23일
- Song hyun
- 작성자
- 2024.05.23.:15
728x90반응형[Java] 98. 코드 리팩토링(1:1 양방향 통신-클라이언트 측)
*자세한 해석, 설명은 아래 글을 참고하자.
https://whatsthatsound.tistory.com/193
(1) MultiThreadClient
package ch05; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; // 1단계 - 함수로 분리해서 리팩토링 진행 public class MultiThreadClient { public static void main(String[] args) { System.out.println("===== 클라이언트 실행 ====="); try (Socket socket = new Socket("localhost",5004)){ System.out.println("=====Connected to the server====="); PrintWriter socketWriter = new PrintWriter(socket.getOutputStream()); BufferedReader socketReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); BufferedReader keyboardReader = new BufferedReader(new InputStreamReader(System.in)); startWriteThread(socketWriter,keyboardReader); startReadThread(socketReader); System.out.println("main 스레드 작업 완료 ..."); } catch (Exception e) { e.printStackTrace(); } } // end of main // 1. 서버로부터 데이터를 읽어들이는 스레드 private static void startReadThread(BufferedReader socketReader) { Thread readThread = new Thread(()->{ try { String serverMessage; while((serverMessage=socketReader.readLine())!=null) { System.out.println("서버에서 온 MSG : "+serverMessage); } } catch (Exception e) { e.printStackTrace(); } }); readThread.start(); waitForThreadToEnd(readThread); } // 2. 서버에게 데이터를 보내는 스레드 private static void startWriteThread(PrintWriter sockerWriter,BufferedReader keyboardReader) { Thread writeThread = new Thread(()->{ try { String clientMessage; while((clientMessage=keyboardReader.readLine())!=null) { sockerWriter.println(clientMessage); } } catch (Exception e) { e.printStackTrace(); } }); writeThread.start(); waitForThreadToEnd(writeThread); } // 3. 워커 스레드가 종료될 때까지 기다리는 메서드 private static void waitForThreadToEnd(Thread thread) { try { thread.join(); } catch (Exception e) { e.printStackTrace(); } } } // end of class
(2) AbstractClient(추상 클래스)
package ch05; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; // 2단계 - 상속 활용 리팩토링 단계 public abstract class AbstractClient { private Socket socket; private BufferedReader socketReader; private PrintWriter socketWriter; private BufferedReader keyboardReader; // set 메서드 // 메서드 의존 주입 (멤버 변수에 참조 변수 할당) protected void setSocket(Socket socket) { this.socket = socket; } // get 메서드 protected Socket getSocket() { return this.socket; } // 실행의 흐름이 필요하다. // final - 상속 받은 자식 클래스에서 수정이 불가 public final void run() { try { setupClient(); setupStream(); startService(); } catch (Exception e) { } finally { cleanup(); } } // 1. 포트 번호 할당 protected abstract void setupClient() throws IOException; // 2. 스트림 초기화 private void setupStream() throws IOException{ socketReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); socketWriter = new PrintWriter(socket.getOutputStream(),true); keyboardReader = new BufferedReader(new InputStreamReader(System.in)); } // 3. 서비스 시작 private void startService() { Thread writeThread = createWriteThread(); Thread readThread = createReadThread(); writeThread.start(); readThread.start(); try { readThread.join(); writeThread.join(); } catch (InterruptedException e) { e.printStackTrace(); } } // 4. 캡슐화 private Thread createWriteThread(){ return new Thread(()->{ try { String msg; while((msg=keyboardReader.readLine())!=null) { socketWriter.println(msg); socketWriter.flush(); } } catch (Exception e) { e.printStackTrace(); } }); } private Thread createReadThread() { return new Thread(()->{ try { String msg; while((msg=socketReader.readLine())!=null) { System.out.println("client 측 msg : "+msg); } } catch (Exception e) { e.printStackTrace(); } }); } // 캡슐화 - 소켓 자원 종료 private void cleanup() { try { if(socket!=null) { socket.close(); } } catch (Exception e) { e.printStackTrace(); } } }
(3) MyClient
package ch05; import java.io.IOException; import java.net.Socket; // 2 -1 상속을 활용한 구현 클래스 설계 하기 public class MyClient extends AbstractClient{ @Override protected void setupClient() throws IOException { // 추상클래스: 자식 클래스는 부모 클래스에게 기능을 상속받아, // 그 기능을 확장하거나 사용한다. // 클라이언트측 소켓 통신 --- 준비물 : 소켓 super.setSocket(new Socket("localhost",5000)); System.out.println(">>> Client was connected on port 5000 <<<"); } public static void main(String[] args) { MyClient myClient = new MyClient(); myClient.run(); } }
728x90반응형'Java > 네트워크 통신' 카테고리의 다른 글
[Java] 100. 네트워크 프로토콜 (0) 2024.05.24 [Java] 99. 1:N 양방향 통신 (0) 2024.05.24 [Java] 97. 코드 리팩토링 (1:1 양방향 통신-서버측) (0) 2024.05.23 [Java] 96. 1:1 양방향 통신(채팅 기본 기능 구현) (0) 2024.05.22 [Java] 95. 1:1 양방향 통신 (서버 측) (0) 2024.05.22 다음글이전글이전 글이 없습니다.댓글
스킨 업데이트 안내
현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)