[JAVA] 소켓 프로그래밍 2번

2024. 7. 8. 12:22·자바

Java 소켓 프로그래밍: 멀티스레딩을 이용한 서버 구현

소개

이전 포스트에서는 Java 소켓 프로그래밍의 기본 개념과 간단한 TCP 에코 서버 및 클라이언트를 구현해보았습니다. 이번 포스트에서는 멀티스레딩을 이용해 다수의 클라이언트와 동시에 통신할 수 있는 서버를 구현해보겠습니다.

멀티스레딩의 필요성

단일 스레드 서버는 한 번에 하나의 클라이언트만 처리할 수 있습니다. 여러 클라이언트가 동시에 서버에 연결을 시도할 경우, 각 클라이언트는 이전 클라이언트의 처리가 완료될 때까지 기다려야 합니다. 이를 해결하기 위해 멀티스레딩을 사용하여 동시에 여러 클라이언트를 처리할 수 있는 서버를 구현할 수 있습니다.

멀티스레딩 서버의 동작 원리

멀티스레딩 서버는 각 클라이언트의 요청을 별도의 스레드에서 처리합니다. 기본적인 동작 과정은 다음과 같습니다:

  1. 서버 소켓 생성: 서버는 특정 포트에서 클라이언트의 연결을 기다립니다.
  2. 클라이언트 연결 수락: 클라이언트의 연결 요청을 수락합니다.
  3. 새 스레드 생성: 각 클라이언트 연결을 처리하기 위해 새 스레드를 생성합니다.
  4. 데이터 송수신: 각 스레드에서 클라이언트와 데이터를 주고받습니다.
  5. 연결 종료: 통신이 끝나면 연결을 종료합니다.

멀티스레딩 에코 서버 예제

서버 코드

먼저 멀티스레딩을 지원하는 서버 코드를 작성해보겠습니다.

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

// 에코 서버 클래스
public class MultithreadedEchoServer {
    public static void main(String[] args) {
        int port = 12345;
        try (ServerSocket serverSocket = new ServerSocket(port)) {
            System.out.println("Multithreaded Echo server is listening on port " + port);

            while (true) {
                // 클라이언트의 연결을 수락
                Socket socket = serverSocket.accept();
                System.out.println("New client connected");

                // 클라이언트를 처리하기 위해 새 스레드 생성
                new EchoClientHandler(socket).start();
            }
        } catch (IOException ex) {
            System.out.println("Server exception: " + ex.getMessage());
            ex.printStackTrace();
        }
    }
}

// 클라이언트 요청을 처리하는 스레드 클래스
class EchoClientHandler extends Thread {
    private Socket socket;

    public EchoClientHandler(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            InputStream input = socket.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(input));

            OutputStream output = socket.getOutputStream();
            PrintWriter writer = new PrintWriter(output, true);

            String text;
            while ((text = reader.readLine()) != null) {
                System.out.println("Received: " + text);
                writer.println("Echo: " + text);
            }

            socket.close();
        } catch (IOException ex) {
            System.out.println("Server exception: " + ex.getMessage());
            ex.printStackTrace();
        }
    }
}

클라이언트 코드

클라이언트 코드는 이전 예제와 동일하게 사용합니다. 여기서 변경된 부분은 없습니다.

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

public class EchoClient {
    public static void main(String[] args) {
        String hostname = "localhost";
        int port = 12345;

        try (Socket socket = new Socket(hostname, port)) {
            OutputStream output = socket.getOutputStream();
            PrintWriter writer = new PrintWriter(output, true);

            InputStream input = socket.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(input));

            BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));
            String text;

            System.out.println("Connected to the echo server. Type your messages:");
            while ((text = consoleReader.readLine()) != null) {
                writer.println(text);
                String response = reader.readLine();
                System.out.println(response);
            }
        } catch (UnknownHostException ex) {
            System.out.println("Server not found: " + ex.getMessage());
        } catch (IOException ex) {
            System.out.println("I/O error: " + ex.getMessage());
        }
    }
}

코드 설명

MultithreadedEchoServer

  • ServerSocket: 특정 포트에서 클라이언트의 연결을 기다립니다.
  • accept(): 클라이언트의 연결을 수락합니다.
  • 새 스레드 생성: 클라이언트의 요청을 처리하기 위해 EchoClientHandler 스레드를 생성하고 시작합니다.

EchoClientHandler

  • Socket: 클라이언트와의 통신을 담당합니다.
  • InputStream과 OutputStream: 클라이언트와 데이터를 주고받기 위한 스트림입니다.
  • BufferedReader와 PrintWriter: 편리하게 데이터를 읽고 쓰기 위해 사용합니다.
  • run(): 스레드가 시작될 때 호출되며, 클라이언트와의 통신을 처리합니다.

결과

멀티스레딩 에코 서버를 통해 여러 클라이언트가 동시에 서버에 연결하여 메시지를 주고받을 수 있습니다. 각 클라이언트는 별도의 스레드에서 처리되므로, 클라이언트 간의 간섭 없이 독립적으로 통신할 수 있습니다.

결론

이번 포스트에서는 멀티스레딩을 이용한 Java 소켓 프로그래밍을 다루었습니다. 이를 통해 다수의 클라이언트를 동시에 처리할 수 있는 서버를 구현하는 방법을 배웠습니다. 다음 포스트에서는 소켓 프로그래밍의 고급 주제들, 예를 들어 비동기 소켓 채널(Asynchronous Socket Channel)과 같은 고급 기술을 다룰 예정입니다.

'자바' 카테고리의 다른 글

[JAVA] 자바 메서드 심화: 오버로딩과 오버라이딩  (0) 2024.07.19
[JAVA] 자바 함수(메서드)의 기초: 선언부터 사용까지  (0) 2024.07.19
[API] Python API와 Java 클라이언트를 이용한 CPK 분석 및 히스토그램 생성  (0) 2024.07.19
[JAVA] 소켓 프로그래밍 3번  (0) 2024.07.08
[JAVA] 소켓 프로그래밍 1번  (0) 2024.07.08
'자바' 카테고리의 다른 글
  • [JAVA] 자바 함수(메서드)의 기초: 선언부터 사용까지
  • [API] Python API와 Java 클라이언트를 이용한 CPK 분석 및 히스토그램 생성
  • [JAVA] 소켓 프로그래밍 3번
  • [JAVA] 소켓 프로그래밍 1번
뚤떡이
뚤떡이
프로그래밍을 알아가며 저와 함께 성장하는 블로그 입니다
  • 뚤떡이
    뚤떡이의 발개벗긴개발
    뚤떡이
  • 전체
    오늘
    어제
    • 분류 전체보기 (73)
      • Docker (2)
      • 자바 (29)
        • start (10)
        • calcu (4)
        • process (7)
      • 플러터 (1)
      • 알고리즘 (12)
        • 개념 (2)
        • 구현 (5)
        • 백준 (0)
        • 프로그래머스 (5)
      • 이클립스 (4)
        • 초기설정 (4)
      • SQL (5)
      • IT 잡동사니 (10)
      • 개발 관련 (10)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    GLPI
    #자동화
    스팸메일 #메일보안 #gophish #it보안 #오픈소스
    IT자산관리
    synology
    #python
    #개발일지
    #apachesuperset #시놀로지 #db2 #데이터시각화 #기술블로그
    윈도우 크롬 원격
    개발일지 #프로젝트후기 #gpt4 #번역 #자동화 #python #electron
    시놀로지
    #electron
    크롬 원격 데스크톱
    #번역
    MAC 크롬 원격
    #python #개발일지 #번역 #메모리최적화 #websocket #redis #비동기프로그래밍
    #프로젝트
    크롬 원격
    요구사항 정의서
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
뚤떡이
[JAVA] 소켓 프로그래밍 2번
상단으로

티스토리툴바