UDP(User Datagram Protocol)은 발신자가 일방적으로 수신자에게 데이터를 보내는 방식으로, TCP처럼 연결 요청 및 수락 과정이 없기 때문에 TCP보다 데이터 전송 속도가 상대적으로 빠르다.
UDP는 TCP처럼 고정 회선이 아니라 여러 회선을 통해 데이터가 전송되기 때문에 특정 회선의 속도에 따라 데이터가 순서대로 전달되지 않거나, 데이터 손실이 발생할 수 있다. 따라서 데이터 전달의 신뢰성보다 속도가 중요하다면 UDP, 신뢰성이 중요하다면 TCP를 사용해야 한다.
자바는 UDP 네트워킹을 위해 java.net 패키지에서 DatagramSocket과 DatagramPacket 클래스를 제공하고 있다.
DatagramSocket datagramSocket = new DatagramSocket(50001);
UDP 서버를 위한 DatagramSocket 객체를 생성할 때에는 다음과 같이 바인딩할 Port 번호를 생성자 매개값으로 제공해야 한다.
UDP 서버는 클라이언트가 보낸 DatagramPacket을 항상 받을 준비를 해야 한다. receive() 메소드를 통해 이루어지는데, 이 메소드는 데이터를 수신할 때까지 블로킹되고, 데이터가 수신되면 매개값으로 주어진 DatagramPacket에 저장한다.
DatagramPacket receivePacket = new DatagramPacket(new byte[1024], 1024);
datagramSocket.receive(receivePacket);
// 수신된 데이터아 바이트 수를 얻는 방법
byte[] bytes = receivePacket.getData();
int num = receivePacket.getLength();
// 읽은 데이터가 문자라면?
String data = new String(bytes, 0, num, "UTF-8");
DatagramPacket의 생성자의 첫 번째 매개값은 수신된 데이터를 저장할 배열이고 두 번째 매개값은 수신할 수 있는 최대 바이트 수이다. 보통 첫 번째 바이트 배열의 크기를 준다.
반대로, UDP 서버가 클라이언트에게 처리 내용을 보내려면 클라이언트 IP 주소와 Port 번호가 필요한데, 이는 receive로 받은 DatagramPacket에서 얻을 수 있다.
SocketAddress socketAddress = receivePacket.getSocketAddress();
String data = "처리 내용"
byte[] bytes = data.getBytes("UTF-8");
DatagramPacket sendPacket = new DatagramPacket(bytes, 0, bytes.length socketAddress);
이렇게 얻은 SocketAddress 객체는 DatagramPacket을 생성할 때 네 번째 매개값으로 사용된다. DatagramPacket 생성자의 첫 번째 매개값은 바이트 배열이고 두 번째는 시작 인덱스, 세 번째는 보낼 바이트 수이다.
DatagramPacket을 클라이언트로 보낼 때는 DatagramSocket의 send() 메솓를, UDP 서버를 종료하고 싶을 때는 close() 메소드를 사용한다.
datagramSocket.send(sendPacket);
datagramSocket.close();
UDP 클라이언트는 서버에 요청 내용을 보내고 그 결과를 받는 역할을 한다.
DatagramSocket datagramSocket = new DatagramSocket();
UDP 클라이언트를 위한 DatagramSocket 객체는 기본 생성자로 생성한다. Port 번호는 자동으로 부여되기 때문에 따로 지정할 필요가 없다.
요청 내용을 보내기 위한 DatagramPacket을 생성해보자.
String data = "요청 내용";
byte[] bytes = data.getBytes("UTF-8");
DatagramPacket sendPacket = new DatagramPacket(
bytes, bytes.length, new InetSocketAddress("localhost", 50001)
);
DatagramPacket의 생성자의 첫 번째 매개값은 바이트 배열이고, 두 번째 매개값은 바이트 배열에서 보내고자 하는 바이트 수이다. 세 번째 매개값은 UDP 서버의 IP와 Port 정보를 가지고 있는 InetSocketAddress 객체이다.
생성된 DatagramPacket을 매개값으로 해서 DatagramSocket의 send() 메소드를 호출하면 UDP 서버로 DatagramPacket이 전송된다.
datagramSocket.send(sendPacket);
더 이상 UDP 서버와 통신할 필요가 없다면 DatagramSocket을 닫기 위해 close() 메소드를 호출한다.
datagramSocket.close();