자바/네트워킹

소켓 프로그래밍: TCP와 UDP(4)

백_곰 2022. 5. 2. 17:25

1. UDP 소켓 프로그래밍

- TCP 소켓 프로그래밍에서는 Socket과 ServerSocket을 사용하지만, UDP 소켓 프로그래밍에서는

DatagramSocketDatagramPacket을 사용한다.

 

- UDP는 비연결지향적인 프로토콜이라서 ServerSocket이 필요하지 않다.

 

- DatagramSocket은 UDP의 소켓이며, 데이터를 DatagramPacket에 담아서 전송한다.

 

- DatagramPacket은 헤더와 데이터로 구성되어 있으며, 보통 헤더는 수신할 호스트의 정보(호스트의 주소, 포트)가

저장되어 있다.

 

 

 

 

1-1. UDP 소켓 프로그래밍을 이해하기 위한 예제(1)

 

( 아래는 서버 프로그램이다. )

package Networking;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Exercise015 {
	public static void main(String args[]) {
		try {
			new Exercise015().start(); // UDP서버를 실행시킨다.
		} catch (IOException e) {
			e.printStackTrace();
		}
	} // main
	
	public void start() throws IOException {
		// 포트 7777번을 사용하는 소켓을 생성한다.
		DatagramSocket socket = new DatagramSocket(7777);
		DatagramPacket inPacket, outPacket;

		byte[] inMsg = new byte[10];
		byte[] outMsg;

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

			// 패킷을 통해 데이터를 수신(receive)한다.
			socket.receive(inPacket);

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

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

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

 

( 아래는 클라이언트 프로그램이다. )

package Networking;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;

public class Exercise016 {
	public void start() throws IOException, UnknownHostException {
		DatagramSocket datagramSocket = new DatagramSocket();
		InetAddress    serverAddress  = InetAddress.getByName("127.0.0.1");

		// 데이터가 저장될 공간으로 byte배열을 생성한다.
		byte[] msg = new byte[100];

		DatagramPacket outPacket = new DatagramPacket(msg, 1, serverAddress, 7777);
		DatagramPacket inPacket  = new DatagramPacket(msg, msg.length);

		datagramSocket.send(outPacket);   // DatagramPacket을 전송한다.
		datagramSocket.receive(inPacket); // DatagramPacket을 수신한다.

		System.out.println("current server time :" + new String(inPacket.getData()));

		datagramSocket.close();
	} // start()

	public static void main(String args[]) {
		try {
			new Exercise016().start();
		} catch(Exception e) {
			e.printStackTrace();
		}
	} // main 
}

 

( 먼저 서버에서 DatagramSocket을 이용하여 클라이언트의 응답을 기다리기 위해 receive()를 써서 기다린다. )

( 그런 다음, 클라이언트의 응답이 오면 답장하기 위해 클라이언트의 주소와 포트 번호를 가져온다. )

 

( 클라이언트는 서버에게 자신의 주소와 포트를 알리기 위해 간단한 1개의 메시지를 전달한다. )

( 그런 다음, 다시 서버에게 receive()를 통해 받은 내용을 getData()를 통해 받는다. )