코딩하는 해달이

[Java] 소켓 통신 구현하기 본문

개인 공부/Java

[Java] 소켓 통신 구현하기

코딩하는 해달 2023. 2. 28. 15:48

Version & 참고 링크

더보기

이 글은 아래의 링크를 바탕으로 작성한 글입니다.

(제가 이해한 대로 글을 쓴 것이므로 틀린 내용이 있을 수도 있습니다.)

https://kadosholy.tistory.com/125

https://junyoung-developer.tistory.com/122

자바를 공부하던 중에 작년 학기중에 배웠던 비주얼 베이직 소켓 통신이 생각 나서 기본적인 소켓 통신 프로그램을 짜 보았다.

 

소켓 통신이란 서버와 클라이언트가 특정 포트를 통해 실시간으로 양방향 통신을 하는 방식이다.

 

내가 만든 프로그램은 서버와 클라이언트가 각각 존재하고

클라이언트는 서버에 메시지를 보낼 수 있으며

서버는 연결된 모든 클라이언트에 메시지를 보낼 수 있다.

 

먼저 서버 프로그램 코드이다.

// TCPServer.java

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

public class TCPServer {
    List<Socket> sockets = new ArrayList<Socket>(); // 소켓 리스트

    TCPServer(ServerSocket socket) {
        ClientSocketReceiver client = new ClientSocketReceiver(socket);
        client.start();

        BufferedReader br2 = new BufferedReader(new InputStreamReader(System.in));

        try {
            while (socket != null) {
                String message;
                message = br2.readLine(); // 서버 메시지 입력 대기

                // 서버와 연결된 모든 클라이언트에게 메시지 전송
                for (Socket s : sockets) {
                    OutputStream out = s.getOutputStream();
                    PrintWriter pw = new PrintWriter(out);

                    pw.println(message);
                    pw.flush();
                }
            }
        } catch (IOException e) {
            System.out.println("Print buffer has problem");
        }
    }

    /*
    * 이 클래스는 클라이언트 소켓의 연결을 대기하는 스레드 형식의 클래스입니다.
     */
    public class ClientSocketReceiver extends Thread {
        private final ServerSocket serverSocket;

        public ClientSocketReceiver(ServerSocket serverSocket) { this.serverSocket = serverSocket; }

        @Override
        public void run() {
            while (serverSocket != null) {
                try {
                    Socket socket = serverSocket.accept(); // 클라이언트 소켓 연결 대기
                    sockets.add(socket);
                    ClientReceiver clientReceiver = new ClientReceiver(socket); // 연결된 소켓에 입력 대기 스레드 부여
                    clientReceiver.start();
                    System.out.println("Client connected");
                } catch (IOException e) {
                    System.out.println("failed to connect" + e);
                }
            }
        }
    }

    /*
    * 이 클래스는 클라이언트의 입력을 대기하는 스레드 형식의 클래스입니다.
    */
    public class ClientReceiver extends Thread {
        private final Socket clientSocket;
        ClientReceiver(Socket socket) {
            this.clientSocket = socket;
        }

        @Override
        public void run() {
            try {
                BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                while (clientSocket != null) {
                    String input = br.readLine(); // 클라이언트 입력 대기
                    System.out.println("Client message : " + input);
                }
            } catch (IOException e) {
                System.out.println("Client disconnected : " + clientSocket);
            }
        }
    }

    public static void main(String[] args) throws IOException {
        TCPServer server = new TCPServer(new ServerSocket(12345));
    }
}

 

다음으로 클라이언트 프로그램이다.

// TCPClient.java

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

public class TCPClient {
    public static void main(String[] args) throws Exception {
        final String serverHostname = "203.232.193.162"; // 서버 IP 주소
        int serverPort = 12345; // 서버 포트번호

        try {
            // 서버에 연결
            Socket clientSocket = new Socket(serverHostname, serverPort);

            // 서버로부터 메시지를 수신하는 쓰레드 생성 및 시작
            ServerReceiver serverReceiver = new ServerReceiver(clientSocket);
            serverReceiver.start();

            // 클라이언트에서 메시지를 전송하는 부분
            while (true) {
                OutputStream out = clientSocket.getOutputStream();
                PrintWriter writer = new PrintWriter(out);
                BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
                String message = reader.readLine();
                writer.println(message);
                writer.flush();
            }
        } catch (SocketException e) {
            // 서버소켓 연결에 실패했을 경우
            System.out.println("Server is not found : " + serverHostname + ":" + serverPort);
        }




    }

    static class ServerReceiver extends Thread {
        private final Socket clientSocket; // 클라이언트 소켓

        ServerReceiver(Socket clientSocket) {
            this.clientSocket = clientSocket;
        }

        @Override
        public void run() {
            try {
                // 서버에서 메시지를 수신하는 부분
                BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

                while (true) {
                    String response = reader.readLine();
                    System.out.println("Response from server: " + response);
                }

            } catch (IOException e) {
                System.out.println("Server is Closed : " + clientSocket);
            }
        }
    }
}
반응형
Comments