자바에서 네트워크 프로그래밍의 Socket을 이용한 서버와 클라이언트 구현에 대해 알아 보겠습니다.

Java는 강력한 네트워크 프로그래밍 기능을 제공하며, 소켓(Socket)을 활용하면 서버와 클라이언트 간의 통신을 쉽게 구현할 수 있습니다. 이번 글에서는 소켓을 이용하여 기본적인 서버와 클라이언트 프로그램을 구현하는 방법을 단계별로 살펴보겠습니다.


1. 소켓(Socket)이란?

소켓은 네트워크 상에서 데이터를 송수신하기 위한 양쪽 끝단을 의미합니다.

  • 서버 소켓(Server Socket): 클라이언트의 연결 요청을 대기하고 처리합니다.
  • 클라이언트 소켓(Client Socket): 서버에 연결 요청을 보내고 데이터를 주고받습니다.

TCP 소켓: 신뢰성이 높은 연결 기반 통신. UDP 소켓: 빠르고 가벼운 비연결 기반 통신.


2. 서버 프로그램 구현하기

다음은 Java에서 TCP 기반의 서버를 구현한 예제입니다.

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

public class ServerExample {
    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(12345)) {
            System.out.println("서버가 12345 포트에서 대기 중입니다...");

            // 클라이언트 연결 대기
            Socket clientSocket = serverSocket.accept();
            System.out.println("클라이언트가 연결되었습니다: " + clientSocket.getInetAddress());

            // 데이터 송수신
            BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);

            String message = in.readLine();
            System.out.println("클라이언트로부터 받은 메시지: " + message);

            out.println("서버에서 답변: " + message.toUpperCase());

        } catch (IOException e) {
            System.out.println("서버 오류: " + e.getMessage());
        }
    }
}

설명:

  1. ServerSocket 객체 생성: 특정 포트(12345)에서 연결 대기.
  2. accept() 메서드: 클라이언트 연결을 수락.
  3. BufferedReaderPrintWriter: 클라이언트와 데이터 송수신.

3. 클라이언트 프로그램 구현하기

클라이언트는 서버에 연결하고 데이터를 주고받습니다.

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

public class ClientExample {
    public static void main(String[] args) {
        try (Socket socket = new Socket("localhost", 12345)) {
            System.out.println("서버에 연결되었습니다.");

            // 데이터 송수신
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);

            out.println("안녕하세요, 서버!");
            String response = in.readLine();
            System.out.println("서버로부터 받은 메시지: " + response);

        } catch (IOException e) {
            System.out.println("클라이언트 오류: " + e.getMessage());
        }
    }
}

설명

  1. Socket 객체 생성: 서버에 연결 요청.
  2. BufferedReaderPrintWriter: 서버와 데이터 송수신.
  3. 서버의 응답 처리.

4. 실행 순서

  1. 서버 프로그램 실행.
  2. 클라이언트 프로그램 실행.
  3. 클라이언트에서 서버로 메시지를 보내고, 서버에서 메시지를 처리하여 응답.

예시 출력

  • 서버
서버가 12345 포트에서 대기 중입니다...
클라이언트가 연결되었습니다: /127.0.0.1
클라이언트로부터 받은 메시지: 안녕하세요, 서버!
  • 클라이언트
서버에 연결되었습니다.
서버로부터 받은 메시지: 안녕하세요, 서버!

5. 네트워크 프로그래밍 시 주의사항

  1. 포트 충돌 방지
    • 동일한 포트를 사용하는 다른 프로세스가 실행 중일 수 있습니다. 포트를 변경하거나 확인하세요.
  2. 에러 처리
    • 네트워크 환경은 예기치 못한 에러가 발생할 수 있으므로 적절한 예외 처리가 필요합니다.
  3. 멀티스레드 서버
    • 다중 클라이언트를 처리하려면 각 클라이언트마다 별도의 스레드를 생성해야 합니다.

멀티스레드 예제

class ClientHandler extends Thread {
    private Socket clientSocket;

    public ClientHandler(Socket socket) {
        this.clientSocket = socket;
    }

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

            String message = in.readLine();
            out.println("서버에서 답변: " + message.toUpperCase());

        } catch (IOException e) {
            System.out.println("클라이언트 처리 중 오류: " + e.getMessage());
        }
    }
}

결론

자바에서 네트워크 프로그래밍의 Socket을 이용한 서버와 클라이언트 구현에 대해 알아 보았습니다. Java의 소켓 프로그래밍은 네트워크 통신을 구현하는 데 매우 유용한 도구입니다. 서버와 클라이언트 간의 기본 통신에서 멀티스레드와 같은 고급 기능으로 확장할 수 있습니다.

다음 블로그에서는 Java에서의 데이터베이스 연결 중 JDBC를 이용한 SQL 쿼리 실행에 대해 알아 보겠습니다. 감사합니다.

Leave a Comment