Java

[Java] 소켓 프로그래밍(Socket Programming) 예제 / ServerSocket, Socket, Thread 프로그래밍

HSRyuuu 2024. 8. 9. 21:15
들어가기 전에, 소켓에 대한 글을 보고 오시는 걸 추천합니다.
[컴퓨터 공학/Web & Network] - [Network] 포트(PORT), 소켓(Socket)이란? (웹소켓 아님 Web Socket != Socket)
 

[Network] 포트(PORT), 소켓(Socket)이란? (웹소켓 아님 Web Socket != Socket)

포트(Port)Port는 운영체제 통신에서의 네트워크 연결이 시작되고 끝나는 논리적인 접속 지점을 말한다. 보통 http://192.168.1.1:8080과 같이 프로토콜/호스트/포트로 구분되어 도메인이 정의된다. 여

innovation123.tistory.com

 

Java 소켓 


Java에서 Socket을 직접 열고, 소켓 통신을 하는 방법을 알아보자.

 

ServerSocket과 ClientSocket을 각각 구현하여 ServerSocket 측에서 소켓을 열고 ClientSocket을 생성하여 ServerSocket과 연결 후 통신하는 과정을 다뤄볼 것이다.

 

ServerSocket은 아래 그림에서 초록색으로 표현된 부분이고,

ClientSocket은 아래 그림에서 파란색으로 표현된 부분이다.


ServerSocket

ServerSocket serverSocket = new ServerSocket(8000);
Socket socket = serverSocket.accept(); // 연결대기 후 Socket 생성

연결 대기용 ServerSocket을 만들고, client가 해당 소켓으로 연결 요청을 하면 연결한 뒤 Socket socket을 새로 생성해서 통신한다.

이외에 코드는 주석을 확인하는 것이 나을 것 같아서, 따로 설명하지 않는다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class ServerMain {
    public static void main(String[] args) {
        BufferedReader in = null;
        PrintWriter out = null;

        ServerSocket serverSocket = null;
        Socket socket = null;
        Scanner scanner = new Scanner(System.in);

        try {
            serverSocket = new ServerSocket(8000);

            System.out.println("[Server실행] Client연결대기중...");
            socket = serverSocket.accept(); // 연결대기

            System.out.println("Client 연결됨."); // Client 연결 시 아래 메시지 출력
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            out = new PrintWriter(socket.getOutputStream());

            while(true) {
                String inputMessage = in.readLine();	// 수신데이터 한줄씩 읽기
                if ("quit".equalsIgnoreCase(inputMessage)) break;

                System.out.println("From Client: " + inputMessage);
                System.out.print("전송하기>>> ");

                String outputMessage = scanner.nextLine();
                out.println(outputMessage); // 서버 콘솔에 출력
                out.flush(); // 클라이언트로 전송
                if ("quit".equalsIgnoreCase(outputMessage)) break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                scanner.close();		// Scanner 닫기
                socket.close();			// Socket 닫기
                serverSocket.close();		// ServerSocket 닫기
                System.out.println("연결종료");
            } catch (IOException e) {
                System.out.println("socket close error");
            }
        }
    }
}

 

ClientSocket

ServerSocket과 유사하지만, Client 측에서는 Socket을 생성해서 ServerSocket 측에 연결 요청만 한다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

public class ClientMain {
    public static void main(String[] args) {
        BufferedReader in = null;
        PrintWriter out = null;

        Socket socket = null;
        Scanner scanner = new Scanner(System.in);

        try {
            // host와 port에 해당하는 소켓 생성 (host: ServerMain (localhost) , port: 8080)
            socket = new Socket("127.0.0.1", 8000);

            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            out = new PrintWriter(socket.getOutputStream());

            while(true) {
                System.out.print("전송하기>>> ");
                String outputMessage = scanner.nextLine();
                out.println(outputMessage); // 클라이언트 콘솔에 출력
                out.flush(); // 서버측 콘솔로 전송
                if ("quit".equalsIgnoreCase(outputMessage)) break;

                String inputMessage = in.readLine();
                System.out.println("From Server: " + inputMessage);
                if ("quit".equalsIgnoreCase(inputMessage)) break;
            }
        } catch (IOException e) {
            System.out.println(e.getMessage());
        } finally {
            try {
                scanner.close();
                if (socket != null) socket.close();
                System.out.println("서버연결종료");
            } catch (IOException e) {
                System.out.println("socket close error");
            }
        }
    }
}

 

테스트

ServerMain을 먼저 실행한 뒤, ClientMain을 실행한다.

이는, ServerSocket이 소켓 통신을 위해 대기할 수 있는 소켓을 미리 열어둬야지 ClientSocket이 여기다 요청을 할 수 있기 때문이다.

반응형