From 0c46bb587e8df62e2132b3d742c7465d45bf7e0a Mon Sep 17 00:00:00 2001 From: kyoohyunlee Date: Tue, 29 Jul 2025 16:50:52 +0900 Subject: [PATCH] =?UTF-8?q?Java=20Network:=20TCP=20=EC=84=9C=EB=B2=84=20?= =?UTF-8?q?=EB=8F=99=EC=8B=9C=EC=9A=94=EC=B2=AD=20=EC=B2=98=EB=A6=AC(?= =?UTF-8?q?=EC=8A=A4=EB=A0=88=EB=93=9C=20=ED=92=80)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../req_execution_threadpool/EchoSercer.java | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 src/step06_network/req_execution_threadpool/EchoSercer.java diff --git a/src/step06_network/req_execution_threadpool/EchoSercer.java b/src/step06_network/req_execution_threadpool/EchoSercer.java new file mode 100644 index 0000000..980fea1 --- /dev/null +++ b/src/step06_network/req_execution_threadpool/EchoSercer.java @@ -0,0 +1,105 @@ +package step06_network.req_execution_threadpool; + +import javax.xml.crypto.Data; +import java.io.DataInputStream; +import java.io.DataOutput; +import java.io.DataOutputStream; +import java.io.IOException; +import java.lang.reflect.Executable; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Scanner; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class EchoSercer { + private static ServerSocket serverSocket = null; + //10개의 스레드로 요청을 처리하는 스레드풀 생성 + private static ExecutorService executorService = + Executors.newFixedThreadPool(10); + + public static void main(String[] args) { + System.out.println("------------------------------------------"); + System.out.println("서버를 종료하려면 q를 입력하고 Enter키를 입력하세요."); + System.out.println("------------------------------------------"); + + //TCP 서버 시작 + startServer(); + + //키보드 입력 + Scanner sc = new Scanner(System.in); + while(true){ + String key = sc.nextLine(); + if(key.toLowerCase().equals("q")){ + break; + } + } + sc.close(); + + //TCP 서버 종료 + stopServer(); + } + + public static void startServer(){ + //작업 스레드 정의 + Thread thread = new Thread(){ + @Override + public void run(){ + try{ + //serverSocket 생성, Port 바인딩 + serverSocket = new ServerSocket(50001); + System.out.println("[서버] 시작됨\n"); + + //연결 수락 및 데이터 통신 + while (true){ + //연결 수락 + Socket socket = serverSocket.accept(); + /** + * 작업 큐에 처리 작업 넣기 + * RUnnable은 함수형 인터페이스라 람다식으로 표현 + */ + executorService.execute(() -> { + try{ + //연결된 클라이언트 정보 얻기 + InetSocketAddress isa = + (InetSocketAddress) socket.getRemoteSocketAddress(); + System.out.println("[서버] "+isa.getHostName()+"의 연결 요청 수락"); + + //데이터 받기 + DataInputStream dis = new DataInputStream( + socket.getInputStream()); + String message = dis.readUTF(); + + //데이터 보내기 + DataOutputStream dos = + new DataOutputStream(socket.getOutputStream()); + dos.writeUTF(message); + dos.flush(); + System.out.println("[서버] 받은 데이터를 다시 보냄 "+message); + + //연결 끊기 + socket.close(); + System.out.println("[서버] "+isa.getHostName()+"의 연결을 끊음\n"); + }catch (IOException e){ + } + }); + } + }catch (IOException e){ + } + } + }; + //스레드 시작 + thread.start(); + } + + public static void stopServer(){ + try{ + //ServerSocket을 닫고 Port 언 바인딩 + serverSocket.close(); + executorService.shutdownNow(); //스레드풀 종료 + System.out.println("[서버] 종료됨 "); + }catch (IOException e){ + } + } +}