[java] 멀티스레드 환경에서의 소켓 통신 처리 방법

소켓 통신은 네트워크 상에서 데이터를 주고받기 위한 중요한 방법 중 하나입니다. 멀티스레드 환경에서 소켓 통신 처리를 구현하는 방법에 대해 알아보겠습니다.

소켓 통신 구현

클라이언트

import java.io.*;
import java.net.*;

public class Client {
    public static void main(String[] args) {
        try (Socket clientSocket = new Socket("localhost", 8080);
             PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
             BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
             BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in))) {

            String userInput;
            while ((userInput = stdIn.readLine()) != null) {
                out.println(userInput);
                System.out.println("echo: " + in.readLine());
            }
        } catch (IOException e) {
            System.err.println("Error: " + e.getMessage());
        }
    }
}

서버

import java.io.*;
import java.net.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Server {
    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(8080)) {
            // 스레드 풀 생성
            ExecutorService executor = Executors.newFixedThreadPool(5);
            
            while (true) {
                Socket clientSocket = serverSocket.accept();
                executor.execute(new ConnectionHandler(clientSocket));
            }
        } catch (IOException e) {
            System.err.println("Error: " + e.getMessage());
        }
    }

    static class ConnectionHandler implements Runnable {
        private final Socket clientSocket;

        ConnectionHandler(Socket socket) {
            this.clientSocket = socket;
        }

        @Override
        public void run() {
            try (PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
                 BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))) {

                String inputLine;
                while ((inputLine = in.readLine()) != null) {
                    out.println(inputLine);
                }
            } catch (IOException e) {
                System.err.println("Error: " + e.getMessage());
            }
        }
    }
}

설명

이 예시에서는 클라이언트와 서버 간의 간단한 에코 통신을 보여줍니다. 클라이언트는 사용자의 입력을 받아 서버에 전송하고, 서버는 받은 메시지를 에코하여 클라이언트에게 다시 보내는 기능을 수행합니다.

서버는 ServerSocket을 사용하여 클라이언트의 연결을 기다리고, 새 클라이언트 연결마다 ExecutorService로부터 받은 스레드를 이용하여 처리합니다. 이를 통해 멀티스레드 환경에서 여러 클라이언트의 동시 요청에 대응할 수 있습니다.

결론

멀티스레드 환경에서의 소켓 통신은 각 클라이언트의 요청을 병렬로 처리할 수 있어야 합니다. 이를 위해 스레드 풀을 사용하여 각 클라이언트 요청에 대한 별도의 스레드를 생성하고 관리하는 것이 중요합니다.

참고문헌: