티스토리 뷰



1. UDP(User Datagram Protocol) 란?

  이제껏 TCP 환경에서의 소켓 송수신을 살펴봤다면 이번엔 UDP 데이터에서 전송되는 네트워크 애플리케이션에 대해 살펴보자. 기본적으로 UDP는 TCP보다 단순한 방식으로 데이터를 주고 받는다. TCP가 데이터의 신뢰성에 초점을 맞춘 방식이라면 UDP는 데이터 전송 속도에 초점을 맞춘 방식이다. 


- UDP의 특징

  • 전송 방식이 매우 단순하고 신뢰성이 낮다.
  • 전송 도중 데이터가 유실되더라도 재전송 하지 않는다.
  • 송신자가 수신자에게 정보가 정확히 전달 되었는지 알 방법이 없다.
  • 데이터가 보낸 순서로 도달 했는지 알 수 없고, 재정립도 하지 않는다.


  그렇다면 왜 이렇게 신뢰성이 한참 떨어지는 프로토콜을 사용하는 것일까? 앞서 말했듯이 속도에 더 초첨을 두어야하는 전송 상황이 발생하게 되는데 이 경우 UDP를 사용한다면 매우 효율적이다. 가령, 오디오나 비디오와 같인 미디어 스트리밍을 TCP로 사용한다면 우린 데이터를 받는데 엄청난 시간이 소요된다. 미디어 전송의 경우 누락되는 데이터가 발생하더라도 끊기지 않고 수신자에게 빠르게 전달 되는 것이 더욱 중요하다. 


- UDP를 사용하는 네트워크 애플리케이션

  • DNS (도메인 주소 서비스)
  • IPTV
  • VoIP
  • TFTP (FTP보다 단순한 파일 전송 프로토콜)
  • 온라인 게임

2. UDP 데이터 구조


  UDP의 경우 TCP 헤더와 비교해서 아주 간결한 포맷을 가진다. TCP의 경우 해당 전송이 몇번째인지 파악하기 위해 존재하는 Sequence Number, Acknowledgement 순서를 알기 위한 Acknowledgement Number 필드와 같이 많은 필드가 필요하다. 하지만 UDP 헤더는 단 4개의 필드만 필요로한다. 소스 포트 번호와 데스티네이션 포트 번호 그리고 헤더와 데이터 필드를 합친 길이를 알 수 있는 Length 필드, 그리고 비트 오류 검증을 위한 CheckSum 필드가 존재한다.


- UDP CheckSum


  총 16bit의 길이로 구성되어 있고, UDP 데이터의 무결성을 검증하기 위해서 사용하게 된다. UDP checksum의 경우 TCP checksum과는 다르게 Optional 한 값이다. UDP는 데이터 무결성을 보장하는 데이터 송수신 방식이 아니므로 Checksum 값이 빠져있더라도 데이터를 주고 받는 데 전혀 지장이 없다. 즉, 0으로 채운채 보내더라도 전혀 상관 없다. 따라서 Checksum 값이 0이라면 수신자 역시 데이터 무결성을 체크하지 않는다.


  CheckSum의 경우 UDP Datagram에 별도의 Pseudo Header를 추가해 만들게 된다. 위 헤더를 활용해 별도의 계산 값을 구하는 방식으로 진행하면 된다. 자세한 사항은 아래 영문 위키 백과를 참조하면 알 수 있다.


Wikipedia-UDP(영문) : https://en.wikipedia.org/wiki/User_Datagram_Protocol#Checksum_computation


3. UDP Client

  UDP를 구현하기 위해서는 Java에서 사용하는 두개의 클래스의 역할은 다음과 같다.


  • DatagramPacket : 데이터를 전송하기 위해서 Packet으로 감싸야 함
  • DatagramSocket : 보내야 되는 패킷을 전송하거나 받은 패킷을 확인하는 역할 수행

  UDP 소켓은 고유의 연결이 존재하지 않으므로, 포트에 데이터가 들어오거나 나오면 별다른 작업을 하지 않고 바로 목적지에 써있는 주소로 보내는 역할만 수행한다. 그렇기 때문에 앞서 채널 방식처럼 단일 연결을 위해 소켓이 할당되지 않는다. 두 패킷이 존재하는 경우 어느 패킷을 먼저 보낼지 결정을 할 필요가 없다. 정확히는 결정을 할 방법이 없다.


  그러므로 클라이언트에서 소켓을 구성하는 경우 포트번호만 명시하더라도 작업이 끝나게 된다. 


<소켓 생성>


DatagramSocket socket = new DatagramSocket(2000);


  위 처럼 2000번 포트에서 작동하는 UDP 소켓을 만들 수 있다.


<패킷 생성>


  그 다음, 패킷을 설정해주어야 한다. 패킷은 송신과 수신 패킷 2가지가 필요하다. 우선 송신 패킷은 아래와 같이 만들 수 있다.


DatagramPacket request = new DatagramPacket(data, length, host, portNumber);


  송신을 위한 패킷을 만들 때에는 데이터 길이, 호스트 정보, 포트 번호를 작성해 주면 된다.


  반대로 수신하는 패킷의 경우 더 간단하게 작성할 수 있다.


DatagramPacket response = new DatagramPacket(data, length);


  수신을 위한 패킷을 만들 때에는 데이터길이 정보만 입력해주면 된다.


<송수신 작업>


  이제 UDP 소켓과 패킷을 만들었이나 소켓을 이용해 패킷을 주고 받으면 된다.


socket.send(request);

socket.receive(response);


<타임 아웃 설정>


  선택적인 작업으로 타임아웃 설정도 가능하다. 송수신이 너무 길어지는 경우를 대비해 타임아웃을 설정해 무한정 대기하고 있는 상황을 빠져 나올 수 있다.


socket.setSoTimeout(10000);


  이를 활용해 UDP 클라이언트를 다음과 같이 설계할 수 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
 
public class Solution {
 
    private final static int PORT = 13;
    private static final String HOST = "172.0.0.1";
    
    public static void main(String[] args) throws SocketException {
        // TODO Auto-generated method stub
        
        // 데이터 객체
        byte[] data = new byte[10];
        
        
        // 소켓 생성
        DatagramSocket socket = new DatagramSocket(0);
        
        try {
            // 소켓 타임아웃 생성
            socket.setSoTimeout(10000);
            InetAddress host = InetAddress.getByName(HOST);
            DatagramPacket request = new DatagramPacket(data, 1, host, PORT);
            DatagramPacket response = new DatagramPacket(data, 1000);
            socket.send(request);
            socket.receive(response);
            String result = new String(response.getData(), 0, response.getLength());
            
            System.out.println(result);
            
        } catch(IOException ex) {
            ex.printStackTrace();
            
        }
        
    }
 
}
 
cs



4. UDP Server

  UDP 서버는 데이터를 전송하기 전에 먼저 수신을 받아야 한다. 그리고 별도의 바인드 과정 없이 포트 번호만 이용해 서버를 구상할 수 있다.


- UDP Server의 특징

  • 별도의 바인딩 과정이 필요 없다.
  • TCP와 달리 멀티스레드 구조로 설계하지 않아도 된다.
  • 응답이 돌아올 때까지 Blocking 과정이 없다

<소켓 생성>


DatagramSocket socket = new DatagramSocket(7);


  7번 포트로 UDP 서버를 구축하는 방법은 위와 같다. UDP 서버에서는 별도의 바인딩 과정은 필요 없다.


<패킷 생성>


  UDP 서버의 경우 데이터를 보내고 받기 위한 송,수신 패킷을 생성한다. 이때는 받은 패킷(requset)에 대해 보낼 패킷(response)의 호스트와 포트 번호를 입력해야한다. 따라서 반대로 패킷을 구성해주면 된다.


DatagramPacket request = new DatagramPacket(data, length);

DatagramPacket response = new DatagramPacket(data, length, host, portNumber);


  UDP 서버는 아래와 같이 구성하면 된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
 
public class Solution {
 
    private final static int PORT = 13;
    private static final String HOST = "172.0.0.1";
    
    public static void main(String[] args) throws SocketException, IOException {
        // TODO Auto-generated method stub
        
        // 데이터 객체
        byte[] data = new byte[10];
        
        
        // 소켓 생성
        DatagramSocket socket = new DatagramSocket(PORT);
        
        while (true){
            try{
                DatagramPacket request = new DatagramPacket(data, data.length);
                socket.receive(request);
                
                byte[] data2 = data;
                DatagramPacket response = new DatagramPacket(data2, data2.length,
                        request.getAddress(), request.getPort());
                socket.send(response);
                
            } catch (IOException | RuntimeException ex){
                ex.printStackTrace();
            }
        }
        
    }
 
}
 
cs



'Skill > Programming - Network' 카테고리의 다른 글

24. IP 멀티캐스트  (0) 2019.10.20
23. UDP 클래스 및 입출력  (0) 2019.10.13
21. 채널 (Channel)  (0) 2019.09.27
20. 버퍼 (Buffer)  (0) 2019.09.20
19. Java NIO (New IO)  (0) 2019.09.11
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함