자바 네트워크 프로그래밍 기초

네트워크 프로그래밍 개요

자바는 출범 초기부터 웹과 밀접한 관련을 맺고 발전해왔습니다. 1995년 Sun World 컨퍼런스에서 넷스케이프 브라우저가 자바를 지원하면서 다양한 기업들이 자바를 채택하게 되었고, 이로 인해 자바는 급속도로 주류 언어로 자리 잡았습니다.

자바에서 제공하는 핵심 네트워크 관련 클래스는 다음과 같습니다: URL, Socket, Datagram입니다.

URL 및 URLConnection 활용

URL 클래스는 웹 리소스의 위치를 나타내며, 가장 추상화된 수준의 네트워크 클래스입니다. 이를 통해 직접적으로 원격 데이터를 읽거나 전송할 수 있습니다.

public static void fetchWebContent() {
    try {
        URL targetUrl = new URL("https://www.google.com");
        InputStream dataStream = targetUrl.openStream();
        InputStreamReader reader = new InputStreamReader(dataStream, "UTF-8");
        BufferedReader buffer = new BufferedReader(reader);
        String contentLine;
        while ((contentLine = buffer.readLine()) != null) {
            System.out.println(contentLine);
        }
    } catch (UnknownHostException ex) {
        ex.printStackTrace();
    } catch (MalformedURLException ex) {
        ex.printStackTrace();
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

URLConnection은 실제 연결을 나타내며, 해당 리소스에 대한 입출력 작업을 수행할 수 있는 객체입니다.

public static void connectToApi() {
    try {
        URL apiEndpoint = new URL("https://api.example.com/data?key=your_api_key");
        URLConnection connection = apiEndpoint.openConnection();
        HttpURLConnection httpConn = (HttpURLConnection) connection;
        
        httpConn.setDoOutput(true);
        httpConn.setDoInput(true);
        httpConn.setUseCaches(false);
        httpConn.setRequestProperty("Content-Type", "application/json");
        httpConn.setRequestMethod("POST");
        httpConn.connect();
        
        InputStream responseStream = httpConn.getInputStream();
        BufferedReader inputBuffer = new BufferedReader(new InputStreamReader(responseStream, "utf-8"));
        BufferedWriter fileWriter = new BufferedWriter(new FileWriter("/tmp/response.json"));
        
        String lineData;
        while ((lineData = inputBuffer.readLine()) != null) {
            fileWriter.write(lineData);
            fileWriter.newLine();
            fileWriter.flush();
        }
    } catch (MalformedURLException ex) {
        ex.printStackTrace();
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

TCP 기반 소켓 통신

소켓은 애플리케이션이 네트워크 요청을 보내거나 응답을 받기 위한 인터페이스입니다. 자바에서는 Socket과 ServerSocket 클래스를 주로 사용합니다.

ServerSocket은 서버측에서 클라이언트 연결을 대기하며, 연결 성립 시 양쪽 모두 Socket 인스턴스를 생성하여 통신합니다. 소켓은 클라이언트/서버 구분 없이 동등하게 작동하며, 내부적으로 SocketImpl 클래스를 통해 구현됩니다.

TCP 소켓 통신 흐름도:

서버 코드:

public static void startServer() {
    try {
        System.out.println("서버 시작 중...");
        ServerSocket listener = new ServerSocket(9090);
        Socket clientSocket = null;
        
        while (true) {
            try {
                clientSocket = listener.accept();
                InputStream input = clientSocket.getInputStream();
                BufferedReader requestReader = new BufferedReader(new InputStreamReader(input));
                PrintWriter responseWriter = new PrintWriter(clientSocket.getOutputStream(), true);
                
                String clientMessage, serverReply;
                while ((clientMessage = requestReader.readLine()) != null) {
                    if ("quit".equals(clientMessage)) {
                        break;
                    }
                    System.out.println("클라이언트 메시지: " + clientMessage);
                    serverReply = "처리 결과: " + handleClientRequest(clientMessage) + 
                                " (요청자: " + clientSocket.getInetAddress().getHostAddress() + ")";
                    responseWriter.println(serverReply);
                }
            } catch (Exception error) {
                System.out.println("통신 오류 발생");
            } finally {
                clientSocket.close();
            }
        }
    } catch (IOException error) {
        error.printStackTrace();
    }
}

클라이언트 코드:

public static void runClient() {
    Socket connection = null;
    try {
        connection = new Socket("192.168.1.100", 9090);
        PrintWriter output = new PrintWriter(connection.getOutputStream(), true);
        InputStream input = connection.getInputStream();
        BufferedReader responseReader = new BufferedReader(new InputStreamReader(input));
        BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));
        
        String userCommand, serverResponse;
        while ((userCommand = userInput.readLine()) != null) {
            output.println(userCommand);
            serverResponse = responseReader.readLine();
            System.out.println(serverResponse);
        }
    } catch (IOException error) {
        error.printStackTrace();
    } finally {
        try {
            connection.close();
        } catch (IOException error) {
            error.printStackTrace();
        }
    }
}

UDP 기반 소켓 통신

UDP(User Datagram Protocol)는 비연결형, 신뢰성 없는 데이터 전송 방식으로, 실시간 스트리밍 등 일부 손실을 감수할 수 있는 상황에서 사용됩니다.

UDP 통신에는 두 가지 주요 클래스가 사용됩니다:

  • DatagramSocket: 데이터그램 패킷 송수신용 소켓
  • DatagramPacket: 데이터그램 패킷 표현 클래스

UDP 소켓 통신 구조도:

수신측(서버) 코드:

public static void udpReceiver() {
    DatagramSocket receiver = null;
    try {
        receiver = new DatagramSocket(8181);
        byte[] receiveBuffer = new byte[1024];
        DatagramPacket packet = new DatagramPacket(receiveBuffer, receiveBuffer.length);
        receiver.receive(packet);
        System.out.println(new String(receiveBuffer));
    } catch (SocketException ex) {
        ex.printStackTrace();
    } catch (IOException ex) {
        ex.printStackTrace();
    } finally {
        receiver.close();
    }
}

송신측(클라이언트) 코드:

public static void udpSender() {
    DatagramSocket sender = null;
    try {
        sender = new DatagramSocket();
        byte[] message = "안녕하세요".getBytes();
        InetAddress targetAddress = InetAddress.getByName("192.168.1.100");
        DatagramPacket packet = new DatagramPacket(message, message.length, targetAddress, 8181);
        sender.send(packet);
    } catch (SocketException ex) {
        ex.printStackTrace();
    } catch (UnknownHostException ex) {
        ex.printStackTrace();
    } catch (IOException ex) {
        ex.printStackTrace();
    } finally {
        sender.close();
    }
}

태그: java network-programming socket tcp UDP

8월 31일 21:12에 게시됨