[java] 소켓 프로그래밍에서의 동기식과 비동기식 통신 방법

이번 포스트에서는 자바 소켓 프로그래밍에서의 동기식(synchronous)비동기식(asynchronous) 통신 방법에 대해 살펴보겠습니다. 소켓 프로그래밍은 네트워크 통신을 위한 핵심 기술로, 동기식과 비동기식은 데이터를 주고받는 방식에 있어 중요한 차이를 나타냅니다.

1. 동기식 통신(Synchronous Communication)

동기식 통신은 클라이언트와 서버 간에 요청과 응답이 순차적으로 이루어지는 방식을 말합니다. 클라이언트가 서버에 요청을 보내면, 해당 요청에 대한 응답이 올 때까지 클라이언트는 대기 상태에 있게 됩니다. 자바에서는 java.net.Socket 클래스를 사용하여 동기식 소켓 통신을 구현할 수 있습니다.

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

public class SyncClient {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("server-ip", 8080);
        // 요청 전송
        PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
        out.println("Hello, server!");
        // 응답 수신
        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String response = in.readLine();
        System.out.println("Server response: " + response);
        // 소켓 종료
        socket.close();
    }
}

2. 비동기식 통신(Asynchronous Communication)

비동기식 통신은 요청과 응답이 별도의 과정으로 이루어지며, 클라이언트는 응답을 기다리지 않고 다른 작업을 수행할 수 있습니다. 자바에서는 java.nio.channels.AsynchronousSocketChannel 클래스와 CompletionHandler를 사용하여 비동기식 소켓 통신을 구현할 수 있습니다.

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;

public class AsyncClient {
    public static void main(String[] args) throws Exception {
        AsynchronousSocketChannel client = AsynchronousSocketChannel.open();
        InetSocketAddress serverAddress = new InetSocketAddress("server-ip", 8080);
        // 연결 요청
        client.connect(serverAddress, null, new CompletionHandler<Void, Void>() {
            @Override
            public void completed(Void result, Void attachment) {
                System.out.println("Client connected to server");
                ByteBuffer buffer = ByteBuffer.allocate(1024);
                // 데이터 전송
                client.write(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
                    @Override
                    public void completed(Integer result, ByteBuffer buffer) {
                        System.out.println("Data sent to server");
                    }
                    @Override
                    public void failed(Throwable exc, ByteBuffer buffer) {
                        System.out.println("Data send failed: " + exc.getMessage());
                    }
                });
            }
            @Override
            public void failed(Throwable exc, Void attachment) {
                System.out.println("Connection to server failed: " + exc.getMessage());
            }
        });
    }
}

마무리

동기식과 비동기식 통신은 각각의 장단점을 가지고 있으며, 상황에 따라 적합한 방식을 선택하여 네트워크 프로그래밍을 구현해야 합니다. 동기식은 간단하고 직관적이지만 응답 대기 시간이 발생할 수 있고, 비동기식은 응답 대기 없이 다른 작업을 수행할 수 있지만 복잡성이 증가할 수 있습니다. 이러한 특성을 고려하여 소켓 프로그래밍을 설계하고 구현해야 합니다.

참고문헌: