1. 개요

이 기사에서는 사용자 데이터 그램 프로토콜 ( UDP )을 통해 Java와의 네트워킹 통신을 살펴볼 것 입니다.

UDP는 도착을 보장하지 않고 배달 순서를 보장하지 않고 네트워크를 통해 독립적 인 패킷전송 하는 통신 프로토콜입니다 .

인터넷을 통한 대부분의 통신은 TCP (Transmission Control Protocol)를 통해 이루어 지지만 UDP에는 다음 섹션에서 살펴볼 위치가 있습니다.

2. 왜 UDP를 사용합니까?

UDP는 일반적인 TCP 와는 상당히 다릅니다 . 그러나 UDP의 표면 수준 단점을 고려하기 전에 오버 헤드가 부족하여 TCP보다 훨씬 빠를 수 있음을 이해하는 것이 중요합니다.

속도 외에도 일부 통신에는 TCP의 안정성이 필요하지 않지만 대신 낮은 대기 시간이 중요하다는 점을 기억해야합니다. 이 비디오는 TCP 대신 UDP를 통해 실행하는 것이 도움이 될 수있는 애플리케이션의 좋은 예입니다.

3. UDP 애플리케이션 구축

UDP 애플리케이션을 구축하는 것은 TCP 시스템을 구축하는 것과 매우 유사합니다. 유일한 차이점은 클라이언트와 서버간에 지점 간 연결을 설정하지 않는다는 것입니다.

설정도 매우 간단합니다. Java는 java.net 패키지의 일부인 UDP에 대한 내장 네트워킹 지원과 함께 제공 됩니다. 따라서 UDP를 통해 네트워킹 작업을 수행하려면 java.net 패키지 ( java.net.DatagramSocketjava.net.DatagramPacket) 에서 클래스 만 가져 오면 됩니다.

다음 섹션에서는 UDP를 통해 통신하는 애플리케이션을 설계하는 방법을 배웁니다. 이 응용 프로그램에 널리 사용되는 에코 프로토콜을 사용할 것입니다.

먼저 전송 된 모든 메시지를 다시 보내는 에코 서버를 구축 한 다음 랜덤의 메시지를 서버로 보내는 에코 클라이언트를 만들고 마지막으로 모든 것이 제대로 작동하는지 애플리케이션을 테스트합니다.

4. 서버

UDP 통신으로, 단일 메시지가 캡슐화된다 DatagramPacket의 관통 보내 DatagramSocket로 .

간단한 서버를 설정하는 것으로 시작하겠습니다.

public class EchoServer extends Thread {

    private DatagramSocket socket;
    private boolean running;
    private byte[] buf = new byte[256];

    public EchoServer() {
        socket = new DatagramSocket(4445);
    }

    public void run() {
        running = true;

        while (running) {
            DatagramPacket packet 
              = new DatagramPacket(buf, buf.length);
            socket.receive(packet);
            
            InetAddress address = packet.getAddress();
            int port = packet.getPort();
            packet = new DatagramPacket(buf, buf.length, address, port);
            String received 
              = new String(packet.getData(), 0, packet.getLength());
            
            if (received.equals("end")) {
                running = false;
                continue;
            }
            socket.send(packet);
        }
        socket.close();
    }
}

패킷을 보내는 데 사용할 전역 DatagramSocket , 메시지를 래핑 할 바이트 배열, running 이라는 상태 변수 만듭니다.

단순화를 위해 서버는 Thread를 확장 하므로 run 메서드 내에서 모든 것을 구현할 수 있습니다 .

run 내부 에서 클라이언트의 오류 또는 종료 메시지로 인해 running 이 false로 변경 될 때까지 실행 되는 while 루프를 만듭니다 .

루프의 맨 위에서 들어오는 메시지를 수신하기 위해 DatagramPacket인스턴스화 합니다.

다음으로 소켓 에서 수신 메소드를 호출합니다 . 이 메서드는 메시지가 도착할 때까지 차단되고 전달 DatagramPacket 의 바이트 배열 내에 메시지를 저장 합니다.

메시지를받은 후 응답을
다시 보낼 것이므로 클라이언트의 주소와 포트를 검색합니다 .

다음으로 클라이언트에 메시지를 보내기위한 DatagramPacket만듭니다 . 수신 패킷과의 서명 차이를 확인하십시오. 이것은 또한 우리가 메시지를 보내는 클라이언트의 주소와 포트를 필요로합니다.

5. 클라이언트

이제이 새 서버를위한 간단한 클라이언트를 배포 해 보겠습니다.

public class EchoClient {
    private DatagramSocket socket;
    private InetAddress address;

    private byte[] buf;

    public EchoClient() {
        socket = new DatagramSocket();
        address = InetAddress.getByName("localhost");
    }

    public String sendEcho(String msg) {
        buf = msg.getBytes();
        DatagramPacket packet 
          = new DatagramPacket(buf, buf.length, address, 4445);
        socket.send(packet);
        packet = new DatagramPacket(buf, buf.length);
        socket.receive(packet);
        String received = new String(
          packet.getData(), 0, packet.getLength());
        return received;
    }

    public void close() {
        socket.close();
    }
}

코드는 서버와 크게 다르지 않습니다. 글로벌 DatagramSocket 과 서버 주소가 있습니다. 생성자 내부에서 인스턴스화합니다.

서버에 메시지를 보내고 응답을 반환하는 별도의 메서드가 있습니다.

먼저 문자열 메시지를 바이트 배열로 변환 한 다음 메시지를 보내기 위한 DatagramPacket만듭니다 .

다음 – 메시지를 보냅니다. DatagramPacket즉시 수신으로 변환합니다 .

에코가 도착하면 바이트를 문자열로 변환하고 문자열을 반환합니다.

6. 테스트

UDPTest.java 클래스에서 두 응용 프로그램의 에코 기능을 확인하는 테스트 하나만 생성합니다.

public class UDPTest {
    EchoClient client;

    @Before
    public void setup(){
        new EchoServer().start();
        client = new EchoClient();
    }

    @Test
    public void whenCanSendAndReceivePacket_thenCorrect() {
        String echo = client.sendEcho("hello server");
        assertEquals("hello server", echo);
        echo = client.sendEcho("server is working");
        assertFalse(echo.equals("hello server"));
    }

    @After
    public void tearDown() {
        client.sendEcho("end");
        client.close();
    }
}

에서 설정 , 우리는 서버를 시작하고 또한 클라이언트를 만듭니다. tearDown 메서드 에있는 동안 서버를 닫고 동시에 클라이언트를 닫을 수 있도록 서버에 종료 메시지를 보냅니다.

7. 결론

이 기사에서 우리는 사용자 데이터 그램 프로토콜에 대해 배우고 UDP를 통해 통신하는 자체 클라이언트-서버 애플리케이션을 성공적으로 구축했습니다.

이 기사에 사용 된 예제에 대한 전체 소스 코드를 얻으려면 GitHub 프로젝트를 확인하십시오 .