Java - 14. 네트워크: UDP

갓김치·2020년 10월 15일
0

고급자바

목록 보기
35/47
post-custom-banner

참고

  • 이것이 자바다 p.1087~1091
  • 교재 p.63~65

UDP: User Datagram Protocol

  • 비연결지향적
  • 데이터의 신뢰성을 보장 하지 않는다
  • TCP에 비해 전송 속도가 빠르다

UDP Datagram 구조

  • IP 헤더 (60bytes)
    • 패킷의 발신지, 목적지 주소, 길이, 체크섬, TTL, 다른 IP 옵션들
  • UDP 헤더 (8bytes)
    • 발신지 포트, 목적지 포트, 헤더 포함 길이, 체크섬
  • UDP 페이로드 (65508bytes, 보통 512bytes로 제한)
    • 실제 데이터

UDP 통신 관련 클래스

DatagramPacket 클래스

  • 클라이언트에게 보낼 데이터를 패킷에 포장하는 역할
  • UDP 데이터그램을 추상화한 클래스
  • 애플리케이션에서 주고 받을 데이터와 관련된 클래스
  • 데이터 송신기능과 수신 기능으로 분리
  • 출발지 주소, 목적지 주소를 설정하거나 주소를 얻어오는 메소드
  • 출잘지 포트, 목적지 포트를 설정하거나 포트를 얻어노는 메소드

주요메서드

  • getAddress(), getData(), getLength(), getOffset(), getPort()
  • setAddress(InetAddress iaddr), setData(byte[ ] butf), setData(byte[ ] buf, int offset, int length), setLength(int length), setPort(int port)

DatagramSocket 클래스

  • 데이터를 보내고 받을 때 사용하는 클래스
  • 패킷에 담긴 데이터를 클라이언트에게 보내는 역할
  • TCP 스트림 소켓과 달리 서버와 클라이언트 데이터그램 소켓 사이에는 차이가 없으며 모든 데이터그램 소켓은 데이터그램을 전송할 뿐만 아니라 수신에 사용할 수 있다
  • 모든 DatagramSocket 객체는 데이터그램을 수신하기 위해서 사용될 수 있기때문에 로컬 호스트 내의 유일한 UDP포트와 연관되어 있다.

주요메서드

  • send(dp), receive(dp), close()
  • getLocalPort()
  • connect(InetAddress address, int port), disconnect()
  • getPort()
  • getInetAddress()

예제1

UdpServer.java

  • 상대방이 UDP방식으로 데이터 보낸 것을 받으려면 무조건 패킷에 담아야하고 그걸 socket의 receive 메서드 이용
  • 소켓을 만들어서 받을 준비하고 있어야 받을 수 있다
  • 준비된 소켓이 없으면 날라온 패킷 파스스..증발..
public class UdpServer {
  private DatagramSocket socket;

  // 1. 시작 메서드
  public void start() throws IOeException {
    // 2. 포트 8888번을 사용하는 소켓 생성
    socket = new DatagramSocket(8888);
    // 3. 패킷 송수신을 위한 객체변수 선언
    DatagramPacket inPacket, outPacket;

    // 4. 패킷 수신을 위한 바이트 배열 선언
    byte[] inMsg = new byte[1];
    // -> Client가 100바이트짜리에서 1만 보내기때문에 Server도 1로 생성

    // 5. 패킷 송신을 위한 바이트 배열 선언
    byte[] outMsg;

    while (true) {
      // 6. 데이터를 수신하기 위한 패킷을 생성
      inPacket = new DatagramPacket(inMsg, inMsg.length);

      System.out.println("패킷 수신 대기중...");

      // 7. 패킷을 통해 데이터를 수신(Receive)한다.
      // 소켓 만들어서 미리 대기하고 있어야함. 없으면 날아온 패킷 증발
      socket.receive(inPacket); // 상대방이 데이터 보내기 전까지  block

      System.out.println("패킷 수신 완료.");

      // 8. 수신한 패킷으로부터 client의 IP주소와 Port번호를 얻는다.
      InetAddress address = inPacket.getAddress();
      int port = inPacket.getPort();

      // 9. 서버의 현재 시간을 시분초 형태([hh:mm:ss])로 반환
      SimpleDateFormat sdf = new SimpleDateFormat("[hh:mm:ss]");
      String time = sdf.format(new Date());
      outMsg = time.getBytes(); // 10. 시간 문자열을 byte배열로 반환

      // 11. 패킷을 생성해서 Client에게 전송(send)
      outPacket = new DatagramPacket(outMsg, outMsg.length, address, port);
      socket.send(outPacket); // 전송시작
    }
  } // start()

  public static void main(String[] args) throws IOException {
    new UdpServer().start();
  } // main()
} UdpServer class

UdpClient.java

public class UdpClient {
  // 1. 시작 메서드
  public void start() throws IOException {
    DatagramSocket datagramSocket = new DatagramSocket();
    InetAddress serverAddress = InetAddress.getByName("127.0.0.1");

    // 2. 데이터가 저장될 공간으로 byte배열을 생성한다 (패킷수신용)
    byte[] msg = new byte[100];

    DatagramPacket outPacket = new DatagramPacket(msg, 1, serverAddress, 8888); // 100바이트짜리 배열에서 1바이트만 전송
    DatagramPacket inPakcet = new DatagramPacket(msg, msg.length); // 100바이트 넘어가는 데이터는 잘림

    datagramSocket.send(outPacket); // 전송
    datagramSocket.receive(inPacket); // 서버가 데이터 보내기 전까지는 block, 그 후 패킷 수신

    System.out.println("현재 서버시간 => " + new String(inPacket.getData()));
    // byte[]에 해당하는 문자열을 만들어주는 String 생성자 이용

    datagramSocket.close(); // 소켓 종료
  } // start()
  public static void main(String[] args) throws IOException {
    new UdpClient().start();
  } // main()
} // UdpClient

실행

Server먼저 실행

Client먼저 실행

  • 패킷 날아가버림

예제2

UdpFileReceiver.java

UdpFileSender.java

profile
갈 길이 멀다
post-custom-banner

0개의 댓글