본문 바로가기
Java

[JAVA] 소켓을 활용한 간단한 에코 서버와 클라이언트

by teamnova 2023. 10. 14.

EchoClient.java, EchoServer.java를 실행하면 클라이언트와 서버가 메시지를 주고 받는 간단한 프로그램을 작성할 수 있습니다. 

 

EchoClient.java

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

public class EchoClient {
    // 서버 주소와 포트 번호를 상수로 설정
    private static final String SERVER_ADDRESS = "localhost";
    private static final int SERVER_PORT = 4444;

    public static void main(String[] args) {
        // try-with-resources를 사용하여 자원을 자동으로 닫게 설정
        // 소켓, 출력 스트림, 입력 스트림을 초기화
        try (
                Socket echoSocket = new Socket(SERVER_ADDRESS, SERVER_PORT);
                PrintWriter out = new PrintWriter(echoSocket.getOutputStream(), true);
                BufferedReader in = new BufferedReader(new InputStreamReader(echoSocket.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.out.println("Exception caught when trying to connect to server " + SERVER_ADDRESS + " on port " + SERVER_PORT);
            System.out.println(e.getMessage());
        }
    }
}

 

EchoServer.java

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

public class EchoServer {

    // 에코 서버의 포트 번호를 상수로 설정
    private static final int ECHO_SERVER_PORT = 4444;

    public static void main(String[] args) {
        // try-with-resources를 사용하여 서버 소켓을 초기화하고 자동으로 닫기
        try (ServerSocket serverSocket = new ServerSocket(ECHO_SERVER_PORT)) {
            System.out.println("Echo Server started at port: " + ECHO_SERVER_PORT);

            // 서버가 실행되는 동안 계속 대기
            while (true) {
                // 클라이언트의 연결 요청을 기다리고 수락
                Socket clientSocket = serverSocket.accept();
                // 새로운 쓰레드에서 클라이언트 요청 처리
                new Thread(new ClientHandler(clientSocket)).start();
            }

        } catch (IOException e) {
            // 포트에서의 수신 또는 연결 수립 중 발생한 예외 처리
            System.out.println("Exception caught when trying to listen on port " + ECHO_SERVER_PORT + " or listening for a connection");
            System.out.println(e.getMessage());
        }
    }

    // 클라이언트 요청을 처리하기 위한 내부 클래스
    static class ClientHandler implements Runnable {
        private Socket clientSocket = null;

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

        @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) {
                    System.out.println("Received: " + inputLine);
                    // 읽은 데이터를 다시 클라이언트에게 전송
                    out.println(inputLine);
                }
            } catch (IOException e) {
                // 데이터 읽기 또는 쓰기 중 발생한 예외 처리
                e.printStackTrace();
            }
        }
    }
}

 

 

pom.xml (maven으로 실행 시 필요합니다. 상황에 따라 필요하지 않을 수 있어요.)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>socket_chat</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

</project>

 

 

실행화면
실행을 여러개 할 수 있도록 하기 위한 세팅. Edit Configurations 클릭.
원하는 어플리케이션을 선택하고, 상단의 Copy Configuration을 클릭하면 실행파일이 여러개로 늘어난다. 여러개를 실행할 수 있게된다.