본문 바로가기

Java 길찾기/Java의 정석

[Java] UDP 소켓 프로그래밍

TCP 소켓 프로그래밍에서는 Socket과 ServerSocket을 사용하지만, UDP 소켓 프로그래밍에서는 DatagramSocket과 DatagramPacket을 사용한다.

앞서 살펴본 바와 같이 UDP는 연결지향적인 프로토콜이 아니기 때문에 ServerSocket이 필요하지 않다. UDP 통신에서 사용하는 소켓은 DatagramSocket이며 데이터를 DatagramPacket에 담아서 전송한다.

 

DatagramPacket은 헤더와 데이터로 구성되어 있으며, 헤더에는 DatagramPacket을 수신할 호스트의 정보(호스트의 주소와 포트)가 저장되어 있다. 소포(packet)에 수신할 상대편의 주소를 적어서 보내는 것과 같다고 이해하면 된다.

그래서 DatagramPacket을 전송하면 DatagramPacket에 지정된 주소(호스트의 포트)의 DatagramSocket에 도착한다.

 

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

public class UdpClient {
    public void start() throws IOException, UnknownHostException {
        DatagramSocket datagramSocket = new DatagramSocket();
        InetAddress serverAddress = InetAddress.getByName("127.0.0.1");
        
        // 데이터가 저장될 공간으로 byte 배열을 생성한다.
        byte[] msg = new byte[100];
        
        DatagramPacket outPacket = new DatagramPacket(msg, 1, serverAddress, 7777);
        DatagramPacket inPacket = new DatagramPacket(msg, msg.length);
        
        datagramSocket.send(outPacket); // DatagramPacket을 전송한다.
        datagramSocket.receive(inPacket) // DatagramPacket을 수신한다.

        System.out.println("current server time : " + new String(intPacket.getData()));
        datagramSocket.close();
    }
    
    public static void main(String args[]) {
        try {
            new UdpClient().start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
import java.net.*;
import java.io.*;
import java.util.Date;
import java.text.SimpleDateFormat;

public class UdpServer {
    public void start() throws IOException {
        // 포트 7777 번을 사용하는 소켓을 생성한다.
        DatagramSocket socket = new DatagramSocket(7777);
        DatagramPacket inPacket, outPacket;

        byte[] inMsg  new byte[10];
        byte[] outMsg;

        while(true) {
            // 데이터를 수신하기 위한 패킷을 생성한다.
            inPacket = new DatagramPacket(inMsg, inMsg.length);

            // 패킷을 통해 데이터를 수신(receive) 한다.
            socket.receive(inPacket);
            
            // 수신한 패킷으로 부터 client의 IP 주소와 Port 를 얻는다.
            InetAddress address = inPacket.getAddress();
            int port = inPacket.getPort();
            
            // 서버의 현재 시간을 시분초 형태([hh::mm:ss]) 로 반환한다.
            SimpleDateFormat sdf = new SimpleDateFormat("[hh:mm:ss]");
            String time = sdf.format(new Date());
            outMsg = time.getBytes(); // time 을 byte 배열로 변환한다.
            
            // 패킷을 생성해서 client에게 전송(send) 한다.
            outPacket = new DatagramPacket(outMsg, outMsg.length, address, port);
            socket.send(outPacket);
        }
    }

    public static void main(String args[]) {
        try {
            // UDP 서버를 실행시킨다.
            new UdpServer().start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

서버로부터 서버시간을 전송받아 출력하는 간단한 UDP 소켓 클라이언트와 서버 프로그램이다. 클라이언트가 DatagramPacket을 생성해서 DatagramSocket으로 서버에 전송하면, 서버는 전송받은 DatagramPacket의 getAddress(), getPort()를 호출해서 클라이언트의 정보를 얻어서 서버시간을 DatagramPacket에 담아서 전송한다.

|참고| UdpClient를 실행하기 전에 UdpServer를 먼저 실행해야 한다.