JAVA/HIGH JAVA

[JAVA] 네트워킹 - UDP

아잠만_ 2024. 5. 10. 12:42

UDP 방식

  • 비연결 지향, 데이터에 대한 신뢰성이 없다. 데이터가 순서대로 도착한다는 보장이 없다.
  • TCP방식보다 속도가 빠르다.
  • DatagramSocket 객체와 DatagramPacket객체를 이용해서 통신한다.
    1. DatagramSocket : 데이터의 송 수신과 관련된 작업을 수행한다. (우체부)
    2. DatagramPacket : 주고 받는 데이터와 관련된 작업을 수행한다. (소포) > 스트림 역할
           ==> 수신을 위한 생성자와 송신을 위한 생성자를 따로 제공한다.
  • TCP의 경우에는 Stream을 이용하여 송수신하지만
    UDP의 경우에는 데이터그램을 이용해서 송수신한다.
  • 받은 패킷에서 주소와 포트번호를 알 수있음
    • 패킷.getAddress()
    • 패킷.getPort()
  • 수신 객체
    DatagramPacket 수신패킷 = new DatagramPacket(수신배열, 수신배열.length);
  • 데이터 수신
    소켓.receive(패킷변수)
    데이터가 올 때 까지 기다린다.
    ==> 수신된 데이터의 패킷정보는 지정된 패킷변수에 저장된다
  • 수신한 메세지 화면에 출력
    • 수신패킷객체.getLength()
      길이 반환
    • 수신패킷객체.getData()
      데이터를 byte배열로 반환
      수신용 패킷 객체를 생성할 때 지정한 byte형 배열에도 저장
    • byte배열을 String으로 변환하기
      String 문자이름 = new String(수신패킷.getData(), 0, 수신패킷.getLength(), "utf-8");
  • 송신 객체
    DatagramPacket 송신패킷 = new DatagramPacket(송신배열, 송신배열.length, address, port);
  • 전송하기
    DatagramSocket 객체의 send()메서드
    소켓객체.send(송신패킷)

Server

더보기
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UdpServer {
	public static void main(String[] args) {
		try {
			// 통신할 포트 번호를 지정하여 소켓객체를 생성한다.
			DatagramSocket socket = new DatagramSocket(8888);
			System.out.println("서버 실행 중...");
			
			while(true) {
				// 수신한 메세지가 저장될 변수 선언
				byte[] inMsg = new byte[1024]; // 한번에 받을 메세지의 크기
				
				// 수신용 패킷 객체 생성하기
				// 		==> 수신한 데이터가 저장될 byte배열, 이 배열의 길이를 인수로
				//			지정하여 객체를 생성한다.
				DatagramPacket inPacket = new DatagramPacket(inMsg, inMsg.length);
				
				// 데이터 수신하기 ==> receive()메서드 이용
				//		==> 이 메서드는 데이터가 올 때 까지 기다린다.
				//		==> 수신된 데이터의 패킷정보는 지정된 패킷변수(inPacket)에 저장된다
				socket.receive(inPacket);
				
				// 받은 패킷에서 상대방의 주소, 포트번호 등을 알 수 있다.
				InetAddress address = inPacket.getAddress();
				int port = inPacket.getPort();
				
				System.out.println("상대방의 IP정보 : "+address);
				System.out.println("상대방의 port정보 : "+port);
				
				// 수신한 메세지 화면에 출력하기
				// 수신한 패킷 객체.getLength() ==> 실제 읽어온 데이터의 길이를 반환한다
				// 수신한 패킷 객체.getData() ==> 실제 읽어온 데이터를 byte배열로 반환한다
				//			==> 수신용 패킷객체를 생성할 때 지정한 byte형 배열에도 저장된다
				
				
				// inMsg의 배열이 다 채워지지않았을 경우 불필요한 데이터가 있을 수 있기 때문에 처리
				String msg = new String(inMsg, 0, inPacket.getLength(), "utf-8");
//				String msg = new String(inPacket.getData(), 0, inPacket.getLength(), "utf-8");

				if("/end".equals(msg)) { // 종료 문자 확인
					break;
				}
				
				System.out.println("수신한 메세지 : "+msg);
				System.out.println();
				
				// 상대방에게 메세지 보내기 (수신 받은 메세지를 그대로 송신한다.)
				
				// 송신할 메세지를 byte형으로 변환
				byte[] sendMsg = msg.getBytes("utf-8");
				
				// 송신용 패킷객체 생성
				// ==> 전송할 데이터가 저장된 byte형 배열, 이 배열의 길이, 
				//     상대방의 주소 정보, 상대방의 포트번호 이렇게 4가지를 지정하여 생성한다.
				DatagramPacket outPacket = new DatagramPacket(sendMsg, sendMsg.length, address, port);
				
				// 전송하기 ==> DatagramSocket객체의 send()메서드 이용
				socket.send(outPacket);
				
				System.out.println("송신완료..");
				System.out.println();
			}
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
}

Client

더보기
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;

public class UdpClient {
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);

		try {
			// 소켓 생성
			DatagramSocket socket = new DatagramSocket();

			// 상대방의 주소 정보 구성하기
//			InetAddress address = InetAddress.getByName("localhost");
			InetAddress address = InetAddress.getByName("127.0.0.1");

			while (true) {
				// 전송할 메세지 입력
				System.out.print("전송할 메세지 입력 >> ");
				String msg = scan.nextLine();

				// 전송용 패킷 객체 생성
				DatagramPacket outPacket = new DatagramPacket(msg.getBytes("utf-8"), 
						msg.getBytes("utf-8").length, address, 8888);

				// 전송하기
				socket.send(outPacket);

				if ("/end".equals(msg)) break;
				
				System.out.println();
				
				// 상대방이 보낸 메세지 받기
				byte[] inMsg = new byte[1024];
				
				// 수신용 패킷객체 생성
				DatagramPacket inPacket = new DatagramPacket(inMsg, inMsg.length);
				
				// 데이터 수신하기
				socket.receive(inPacket);
				
				String message = new String(inMsg, 0, inPacket.getLength(),"utf-8");
				System.out.println("서버에서 보내온 메세지 : "+message);
				System.out.println();
			}
			
			System.out.println("통신 끝...");
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
}