본문 바로가기

Java/기본

[Java] 네트워킹 - UDP

UDP 네트워킹

  • UDP 특징
    • user datagram protocol → 사용자 데이터그램 방식
    • 연결되었는지 확인하지 않고 데이터를 전송함
    • 데이터를 전송했지만 실제로 수신했는지는 모름
    • 데이터가 수신자한테 갈 수도 있고, 가다가 유실될 수도 있음
    • 빠른 전송, 실시간 전송 가능
    • 전송된 데이터 순서가 엉킬 수 있음
    • ex) (던진다는 말 없음, 몇번째 공인지도 알려주지 않고) 공 던지기 (공 받았는지 확인 안함)

 

  • Java UDP 네트워킹
    • 서버와 클라이언트의 데이터 통신은 DatagramSocket 과 DatagramPacket 객체를 사용한다
    • TCP 와는 다르게 DatagramSocket 은 송수신 둘다 가능하다
클래스 역할
java.net.DatagramSocket 데이터를 주고받을 수 있는 소켓 객체를 생성하고 사용하는 클래스이다
java.net.DatagramPacket UDP에서 데이터를 전송받기 위해서는 DatagramPacket 에 데이터를 탑재하는 방식으로 전송할 수 있다.

 


DatagramSocket

데이터를 주고받을 수 있는 소켓 객체를 생성하고 사용하는 클래스이다

 

  • DatagramSocket 주요 생성자
생성자 내용
DatagramSocket() 기본 생성자
DatagramSocket(int port) 포트 인자값으로 주기
DatagramSocket(int port, InetAddress laddr) 포트, InetAddress 인자값으로 주기
DatagramSocket(SocketAddress bindaddr) SocketAddress 인자값으로 주기

 

 

  • DatagramSocket 주요 메서드

송수신에 사용되는 메서드는 receive() 와 send() 이다

메서드 내용
void  bind(SocketAddress addr) 특정 주소에 바인딩하기
void  close() 소켓 닫기
void  connect(InetAddress address, int port) 연결하기
void  connect(SocketAddress addr) 연결하기
InetAddress  getInetAddress() 연결된 InetAddress  리턴
InetAddress  getLocalAddress() 바인딩된 InetAddress  리턴
int  getLocalPort() 바인딩된 포트 리턴
SocketAddress  getLocalSocketAddress() 바인딩된 SocketAddress  리턴
int  getPort() 연결된 포트 리턴
boolean  isClosed() 닫혔는지 여부 리턴
boolean  isConnected() 연결되었는지 여부 리턴
void  receive(DatagramPacket p) 데이터그램 패킷 수신하기
void  send(DatagramPacket p) 데이터그램 패킷 송신하기

 

 

아래 코드를 보자

Datagram을 생성하고 포트 7000을 할당했다.

public class Test01 {
    public static void main(String[] args) throws SocketException {
        DatagramSocket ds = new DatagramSocket();
        ds.connect(new InetSocketAddress(7000));
        System.out.println("isConnected : "+ ds.isConnected());
        System.out.println("port : "+ ds.getPort());
        System.out.println("localAddr : "+ ds.getLocalAddress());
        System.out.println("localPort : "+ ds.getLocalPort());
        if(!ds.isClosed()){ ds.close(); }
    }
}

 

실행 결과

isConnected : true
port : 7000
localAddr : 0.0.0.0/0.0.0.0
localPort : 54210

 


DatagramPacket

UDP에서 데이터를 전송받기 위해서는 DatagramPacket 에 데이터를 탑재하는 방식으로 전송할 수 있다.

 

  • DatagramPacket 주요 생성자

-인자값 byte배열 buf 는 전송할 데이터이다.

-인자값 offset 은 byte배열의 시작인덱스 이다.

-수신용은 1개, 나머지는 송신용이다

생성자 내용
DatagramPacket(
   byte[] buf, int length)
-수신용 패킷 생성
-length 에 해당하는 데이터를 받을 수 있음
DatagramPacket(
   byte[] buf, int length,
   InetAddress address, int port)
-송신용 패킷 생성
-데이터 길이와 주소값 할당
DatagramPacket(
   byte[] buf, int offset, int length)
-송신용 패킷 생성
-데이터 길이와 offset 할당
DatagramPacket(
   byte[] buf, int offset, int length,
   InetAddress address, int port)
-송신용 패킷 생성
-데이터 길이와 offset, 주소값 할당
DatagramPacket(
   byte[] buf, int offset, int length,
   SocketAddress address)
-송신용 패킷 생성
-데이터 길이와 offset, 주소값 할당
DatagramPacket(
   byte[] buf, int length, SocketAddress address)
-송신용 패킷 생성
-데이터 길이와 주소값 할당

 

 

  • DatagramPacket  주요 메서드
메서드 내용
InetAddress  getAddress() (데이터를 보내거나 받을) 상대방 ip 얻기
byte[]  getData() 데이터 버퍼 리턴
int  getLength() 데이터 길이 리턴
int  getOffset() offset 리턴
int  getPort() (데이터를 보내거나 받을) 상대방 port 얻기
SocketAddress  getSocketAddress() (데이터를 보내거나 받을) 상대방 SocketAddress 얻기
void  setAddress(InetAddress iaddr) 전송할 ip 설정
void  setData(byte[] buf) 전송할 데이터 설정
void  setData(byte[] buf, int offset, int length) 전송할 데이터 설정
void  setLength(int length) 전송할 데이터 길이 설정
void  setPort(int iport) 전송할 port 설정
void  setSocketAddress(SocketAddress address) 전송할 SocketAddress 설정

 

 

 

DatagramPacket 생성하기1

byte[] byteArr = new byte[]{};
new DatagramPacket(
		byteArr,
		byteArr.length
);

 

DatagramPacket 생성하기2

byte[] byteArr = new byte[]{};
new DatagramPacket(
		new byte[]{},
		byteArr.length,
		new InetSocketAddress("localhost", 7000)
);

 


객체를 생성하고 데이터를 송수신할 수 있는 코드를 짜본다

UDP는 각 클래스가 송수신이 가능하므로 서버-클라이언트가 아닌, sender-receiver 로 코딩한다

 

Sender

public class Test_sender {
    public static void main(String[] args) {
        DatagramSocket datagramSocket = null;
        try {
            datagramSocket = new DatagramSocket();
        } catch (SocketException se){
            se.printStackTrace();
        } finally {
            if(datagramSocket != null) { datagramSocket.close(); }
        }
    }
}

 

Receiver

public class Test_receiver {
    public static void main(String[] args) {
        DatagramSocket datagramSocket = null;
        try {
            datagramSocket = new DatagramSocket();
        } catch (SocketException se){
            se.printStackTrace();
        } finally {
            if(datagramSocket != null){ datagramSocket.close(); }
        }
    }
}