๊ด€๋ฆฌ ๋ฉ”๋‰ด

<Hello Hosung๐Ÿ˜Ž/>

[Java] ์†Œ์ผ“ํ†ต์‹ ์˜ ๊ธฐ์ดˆ(+์ฑ„ํŒ…๐Ÿง) ๋ณธ๋ฌธ

๐Ÿ’ป Java/ใ…คJava(Basic)

[Java] ์†Œ์ผ“ํ†ต์‹ ์˜ ๊ธฐ์ดˆ(+์ฑ„ํŒ…๐Ÿง)

์ขŒ์ถฉ์šฐ๋Œ ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž ์ผ๊ธฐ๐Ÿง 2024. 11. 7. 06:54

์†Œ์ผ“(Socket)์€ ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์–‘๋ฐฉํ–ฅ ํ†ต์‹  ์ฑ„๋„์ž…๋‹ˆ๋‹ค. ์ž๋ฐ”์—์„œ๋Š” java.net ํŒจํ‚ค์ง€๋ฅผ ํ†ตํ•ด ์†Œ์ผ“ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ธ€์—์„œ๋Š” ์ž๋ฐ” ์†Œ์ผ“ ํ†ต์‹ ์„ ์ด์šฉํ•˜์—ฌ ๊ฐ„๋‹จํ•œ ์ฑ„ํŒ… ํ”„๋กœ๊ทธ๋žจ์„ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

1. ์†Œ์ผ“ ํ†ต์‹ ์˜ ๊ธฐ๋ณธ ์ดํ•ด


์†Œ์ผ“ ํ†ต์‹ ์€ ํฌ๊ฒŒ ๋‘ ๊ฐ€์ง€๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

์„œ๋ฒ„(Server): ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์‹ ํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ์™€ ์—ฐ๊ฒฐ์„ ๊ด€๋ฆฌํ•˜๋Š” ์—ญํ• 
ํด๋ผ์ด์–ธํŠธ(Client): ์„œ๋ฒ„์— ์ ‘์†ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›๋Š” ์—ญํ• 
์„œ๋ฒ„๋Š” ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ๋Œ€๊ธฐํ•˜๋ฉฐ ์—ฐ๊ฒฐ์„ ์ˆ˜๋ฝํ•˜๊ณ , ํด๋ผ์ด์–ธํŠธ๋Š” ์„œ๋ฒ„์— ์—ฐ๊ฒฐ ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๋Š” InputStream๊ณผ OutputStream์„ ํ†ตํ•ด ์ฃผ๊ณ ๋ฐ›์Šต๋‹ˆ๋‹ค.

2. ์ฑ„ํŒ… ์„œ๋ฒ„ ๊ตฌํ˜„


์ฑ„ํŒ… ์„œ๋ฒ„๋Š” ํด๋ผ์ด์–ธํŠธ์˜ ์—ฐ๊ฒฐ์„ ๋ฐ›๊ณ , ๋ฉ”์‹œ์ง€๋ฅผ ํด๋ผ์ด์–ธํŠธ๋“ค์—๊ฒŒ ์ „๋‹ฌํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

์„œ๋ฒ„ ์ฝ”๋“œ (ChatServer.java)

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

public class ChatServer {
    private static final int PORT = 12345;
    private static Set<PrintWriter> clientWriters = new HashSet<>();

    public static void main(String[] args) {
        System.out.println("์ฑ„ํŒ… ์„œ๋ฒ„ ์‹œ์ž‘...");
        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            while (true) {
                new ClientHandler(serverSocket.accept()).start();
            }
        } catch (IOException e) {
            System.err.println("์„œ๋ฒ„ ์˜ค๋ฅ˜: " + e.getMessage());
        }
    }

    private static class ClientHandler extends Thread {
        private Socket socket;
        private PrintWriter out;
        private BufferedReader in;

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

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

                synchronized (clientWriters) {
                    clientWriters.add(out);
                }

                String message;
                while ((message = in.readLine()) != null) {
                    System.out.println("ํด๋ผ์ด์–ธํŠธ ๋ฉ”์‹œ์ง€: " + message);
                    synchronized (clientWriters) {
                        for (PrintWriter writer : clientWriters) {
                            writer.println(message);
                        }
                    }
                }
            } catch (IOException e) {
                System.err.println("ํด๋ผ์ด์–ธํŠธ ์—ฐ๊ฒฐ ์‹คํŒจ: " + e.getMessage());
            } finally {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                synchronized (clientWriters) {
                    clientWriters.remove(out);
                }
            }
        }
    }
}


3. ์ฑ„ํŒ… ํด๋ผ์ด์–ธํŠธ ๊ตฌํ˜„


์ฑ„ํŒ… ํด๋ผ์ด์–ธํŠธ๋Š” ์„œ๋ฒ„์— ์—ฐ๊ฒฐํ•˜๊ณ , ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๋ฉ”์‹œ์ง€๋ฅผ ์„œ๋ฒ„๋กœ ์ „์†กํ•ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„์—์„œ ๋ณด๋‚ธ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›์•„์„œ ํ™”๋ฉด์— ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ (ChatClient.java)

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

public class ChatClient {
    private static final String SERVER_ADDRESS = "localhost";
    private static final int SERVER_PORT = 12345;

    public static void main(String[] args) {
        try (Socket socket = new Socket(SERVER_ADDRESS, SERVER_PORT);
             BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));
             BufferedReader serverInput = new BufferedReader(new InputStreamReader(socket.getInputStream()));
             PrintWriter serverOutput = new PrintWriter(socket.getOutputStream(), true)) {

            // ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ์Šค๋ ˆ๋“œ
            Thread listenerThread = new Thread(() -> {
                try {
                    String message;
                    while ((message = serverInput.readLine()) != null) {
                        System.out.println("์„œ๋ฒ„: " + message);
                    }
                } catch (IOException e) {
                    System.err.println("์„œ๋ฒ„์™€์˜ ์—ฐ๊ฒฐ์ด ๋Š์–ด์กŒ์Šต๋‹ˆ๋‹ค.");
                }
            });
            listenerThread.start();

            // ์‚ฌ์šฉ์ž ์ž…๋ ฅ์„ ์„œ๋ฒ„๋กœ ์ „์†กํ•˜๋Š” ๋ถ€๋ถ„
            String userMessage;
            while ((userMessage = userInput.readLine()) != null) {
                serverOutput.println(userMessage);
            }

        } catch (IOException e) {
            System.err.println("ํด๋ผ์ด์–ธํŠธ ์—ฐ๊ฒฐ ์‹คํŒจ: " + e.getMessage());
        }
    }
}


4. ์ฑ„ํŒ… ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰


1. ์„œ๋ฒ„ ์‹คํ–‰: ๋จผ์ € ์„œ๋ฒ„ ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„๋Š” ํด๋ผ์ด์–ธํŠธ๋“ค์˜ ์—ฐ๊ฒฐ์„ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
java ChatServer

2. ํด๋ผ์ด์–ธํŠธ ์‹คํ–‰: ์—ฌ๋Ÿฌ ํด๋ผ์ด์–ธํŠธ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ์„œ๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ์ฃผ๊ณ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
java ChatClient


5. ๋™์ž‘ ์›๋ฆฌ

ํด๋ผ์ด์–ธํŠธ๋Š” Socket์„ ํ†ตํ•ด ์„œ๋ฒ„์— ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.
์„œ๋ฒ„๋Š” ํด๋ผ์ด์–ธํŠธ์˜ ์—ฐ๊ฒฐ์„ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ์œผ๋ฉฐ, ์—ฐ๊ฒฐ์ด ์ด๋ฃจ์–ด์ง€๋ฉด ClientHandler ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ํ•ด๋‹น ํด๋ผ์ด์–ธํŠธ์™€์˜ ํ†ต์‹ ์„ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
ํด๋ผ์ด์–ธํŠธ๋Š” ์ž…๋ ฅํ•œ ๋ฉ”์‹œ์ง€๋ฅผ ์„œ๋ฒ„๋กœ ์ „์†กํ•˜๊ณ , ์„œ๋ฒ„๋Š” ํ•ด๋‹น ๋ฉ”์‹œ์ง€๋ฅผ ๋ชจ๋“  ์—ฐ๊ฒฐ๋œ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ๋Š” ๊ฐ๊ฐ BufferedReade์™€ PrintWriter๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์†ก์ˆ˜์‹ ํ•ฉ๋‹ˆ๋‹ค.


6. ๋งˆ๋ฌด๋ฆฌ


์ด๋ฒˆ ํฌ์ŠคํŠธ์—์„œ๋Š” ์ž๋ฐ” ์†Œ์ผ“ ํ†ต์‹ ์„ ์ด์šฉํ•˜์—ฌ ๊ฐ„๋‹จํ•œ ์ฑ„ํŒ… ํ”„๋กœ๊ทธ๋žจ์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ํ”„๋กœ๊ทธ๋žจ์€ ๋ฉ€ํ‹ฐ ํด๋ผ์ด์–ธํŠธ ํ™˜๊ฒฝ์—์„œ๋„ ์ž˜ ์ž‘๋™ํ•˜๋ฉฐ, ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ์ฃผ๊ณ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์†Œ์ผ“ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ†ตํ•ด ๋„คํŠธ์›Œํฌ ํ†ต์‹ ์— ๋Œ€ํ•œ ๊ธฐ์ดˆ๋ฅผ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์—ˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.