elevne's Study Note

Java - Socket(UDP) 본문

Backend/Java

Java - Socket(UDP)

elevne 2023. 5. 26. 12:20

UDP (User Datagram Protocol)비연결 지향적 프로토콜이다. 비연결 지향적이란 데이터를 주고받을 때 연결 절차를 거치지 않고, 발신자가 일방적으로 데이터를 발신하는 방식이다. 연결 과정이 없기 떄문에 TCP 보다는 빠른 전송이 가능하지만 데이터 전달의 신뢰성이 떨어진다는 단점이 있다. UDP 는 발신자가 데이터 패킷을 순차적으로 보내더라도 이 패킷들은서로 다른 통신 선로를 통해 전달될 수 있기 때문에 먼저 보낸 패킷이 나중에 보낸 것보다 늦게 도착할 수도 있다. 일반적으로 데이터 전달의 신뢰성보다 속도가 중요한 프로그램에서 UDP 를 사용한다. 이를 구현하기 위해 Java 에서는 java.net.DatagramSocket, java.net.DatagramPacket 클래스를 제공한다.

 

 

 

Server

 

public class UDPServerExample {

    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(5001);
        Thread thread = new Thread(){
            @Override
            public void run() {
                System.out.println("수신 시작");
                try {
                    while(true){
                        DatagramPacket packet = new DatagramPacket(new byte[100], 100);
                        socket.receive(packet);

                        String data = new String(packet.getData(), 0, packet.getLength(), "UTF-8");
                        System.out.println("받은 내용: "+packet.getSocketAddress()+" :"+data);
                    }
                } catch (Exception e) {
                    System.out.println("수신 종료");
                }
            }
        };
        thread.start();
        Thread.sleep(5000);
        socket.close();
    }
}

 

 

 

Client

 

public class UDPClientExample {

    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket();
        System.out.println("발신 시작");
        for (int i = 0; i < 3; i++) {
            String data = "MESSAGE NO."+i;
            byte[] byteArr = data.getBytes("UTF-8");
            DatagramPacket packet = new DatagramPacket(
                    byteArr, byteArr.length, new InetSocketAddress("localhost", 5001)
            );

            socket.send(packet);
            System.out.println("보낸 바이트 수: "+byteArr.length);
        }
        System.out.println("발신 종료");
        socket.close();
    }

}

 

 

 

result (server)

 

 

 

Server 코드에서 DatagramSocket 객체를 생성하며 바인딩할 포트 번호를 매개값으로 넘긴다. DatagramSocket 은 recieve() 메소드를 호출해서 패킷을 읽을 준비를 하는데, receive() 메소드는 패킷을 받을 때까지 블로킹되고 패킷이 도착하면 매개값으로 주어진 DatagramPacket 에 패킷 내용을 저장한다. 만약 수신자가 패킷을 받고 나서 발신자에게 응답 패킷을 보내고 싶다면 발신자의 IP 와 포트를 알아야 하는데, 이는 위 코드처럼 getSocketAddress() 메소드를 통해 알아볼 수 있다. 얻은 종보를 사용하여 send() 메소드를 사용하면 된다.

 

 

데이터를 보내는 Client 측에서는 따로 포트바인딩을 해줄 필요가 없으니 DatagramSocket 생성 시 인자가 필요없다. 보낼 패킷 데이터는 DatagramPacket 객체로 생성한다. 생성 시 첫 번째 매개값은 보낼 데이터의 byte 배열, 두 번째는 바이트 배열의 보내고자 하는 항목의 수, 마지막으로는 수신자 IP 와 포트 정보를 담은 SocketAddress 이다. 마지막으로 socket.send(packet) 을 해주면 데이터가 전송되는 것이다.

 

 

 

 

 

 

Reference:

이것이 자바다

'Backend > Java' 카테고리의 다른 글

Java - NIO (1)  (0) 2023.05.28
Java - Reflection  (1) 2023.05.27
Java - Socket(TCP)  (0) 2023.05.25
Java - Network, IP  (0) 2023.05.24
Java - Optional  (0) 2023.05.23