본문 바로가기
Code/Console

[Java Code] 소켓 양방향 통신 구현

by 스응 2023. 3. 4.
728x90
728x90

  - 서버와 클라이언트는 서로 키보드로 입력한 메세지를 주고 받을 수 있음

 

서버 측 코드

public class ServerTest {

    // 클라이언트를 연결받는 소켓
    ServerSocket serverSocket;

    // 실제 통신을 담당할 소켓
    Socket socket;

    // 키보드 담당 입력 스트림
    BufferedReader keyboardReader;

    // 소켓 담당 입력 스트림
    BufferedReader socketReader;

    // 소켓 담당 출력 스트림
    BufferedWriter socketWriter;

    public ServerTest() {
        initData();
    } 

    private void initData() {
        try {
            System.out.println("서버 실행");
            // 서버 소켓 생성
            serverSocket = new ServerSocket(10000); // 매개변수 : 포트 번호

            // 클라이언트 접속 대기 (접속 전까지는 여기서 멈춰 있음)
            socket = serverSocket.accept(); // 클라이언트가 접속하면 socket을 반환함
            // 점유하고 있지 않은 랜덤 포트 번호를 생성해서, 소켓 생성

            // 클라이언트가 연결되면 해당 텍스트 출력
            System.out.println("클라이언트 연결 완료");

            // 스트림 연결
            socketReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            socketWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            keyboardReader = new BufferedReader(new InputStreamReader(System.in));

            // while 문을 2개 구동해야 하므로, 하나는 내부 클래스 쓰레드로 구동
            new Thread(new KeyboardThread()).start();

            // 메인 쓰레드의 무한 루프 while 문은 가장 아래에 있어야 정상 작동함
            while (true) {
                // 클라이언트로부터 보내진 메세지를 읽음
                String clientMsg = socketReader.readLine();
                System.out.println("클라이언트 >>> " + clientMsg);
            }


        } catch (IOException e) {
            e.printStackTrace();

        } finally {
            try {
                keyboardReader.close();
                socketWriter.close();
                socketReader.close();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    } // end of initData

    // 키보드 입력을 받고 소켓으로 보내는 클래스
    class KeyboardThread implements Runnable {

        @Override
        public void run() {
            while (true) {
                try {
                    // 키보드 데이터 받아오기
                    String serverMsg = keyboardReader.readLine();

                    // 소켓으로 메세지 보내기
                    socketWriter.write(serverMsg + "\n");
                    socketWriter.flush();

                } catch (IOException e) {
                    e.printStackTrace();
                }
            } // end of while
        }
    } // end of inner class

    public static void main(String[] args) {
        new ServerTest();
    }
} // end of outer class

 

클라이언트 측 코드

public class ClientTest {

    final String MY_IP = "localhost";
    final int PORT = 10000;

    // 실제 통신을 담당할 소켓
    Socket socket;

    // 키보드 담당 입력 스트림
    BufferedReader keyboardReader;

    // 소켓 담당 입력 스트림
    BufferedReader socketReader;

    // 소켓 담당 출력 스트림
    BufferedWriter socketWriter;

    public ClientTest() {
        initData();
    }

    private void initData() {
        System.out.println("클라이언트에서 서버 접속 요청");
        try {
            // 클라이언트와 서버 연결
            socket = new Socket(MY_IP, PORT); // 서버IP주소, 서버포트주소

            // 서버에 연결되면 해당 텍스트 출력
            System.out.println("서버에 연결 완료")

            // 스트림 연결
            keyboardReader = new BufferedReader(new InputStreamReader(System.in));
            socketReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            socketWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

            // while 문을 2개 구동해야 하므로, 하나는 내부 클래스 쓰레드로 구동
            new Thread(new KeyboardThread()).start();

            while (true) {
                // 서버로부터 보내진 메세지를 읽음
                String serverMsg = socketReader.readLine();
                System.out.println("서버 >>> " + serverMsg);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                keyboardReader.close();
                socketWriter.close();
                socketReader.close();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    } // end of initData

    class KeyboardThread implements Runnable {

        @Override
        public void run() {
            try {
                // 키보드 데이터 받아오기
                String clientMsg = keyboardReader.readLine();

                // 소켓으로 메세지 보내기
                socketWriter.write(clientMsg + "\n");
                socketWriter.flush();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    } // end of inner class

    public static void main(String[] args) {
        new ClientTest();
    }
} // end of outer class

 

320x100
반응형

댓글