안녕하세요 알통몬입니다. 공감 및 댓글은 포스팅 하는데 아주아주 큰 힘이 됩니다!! 포스팅 내용이 찾아주신 분들께 도움이 되길 바라며 더 깔끔하고 좋은 포스팅을 만들어 나가겠습니다^^
|
UDP 채널 :
NIO에서 UDP 채널은 DatagramChannel 입니다. DatagramChannel도 TCP 채널과 마찬가지로
블로킹 방식과 넌 블로킹 방식이 있습니다
발신자 :
DatagramChannel 을 생성하기 위해서는 open()을 호출해야 합니다.
open() 은 ProtocolPamily 인스턴스 타입의 매개값을 가집니다.
=> 이 객체의 역할은 IPv4 와 IPv6를 구분하는 역할을 합니다.
구현 객체는 StandardProtocalFamily 열거 상수를 사용합니다.
DatagramChannel datagramChannel = DatagramChannel.open(StandardProtocolFamily.INET);
DatagramChannel을 이용해 데이터를 보내려면 send()메서드 사용.
첫 매개값은 보낼 데이터를 가지는 ByteBuffer이고, 두번 째 매개값은 IP와 포트 정보를 가지고 있는
SocketAddress.
SocketAddress는 추상 클래스 => 하위 클래스인 InetSocketChannel객체를 생성하고 대입.
send()의 리턴 값은 실제 보낸 바이트 수
ex)
int byteCount = datagramChannel.send(byteBuffer, new InetSocketAddress("localhost", 5001));
더이상 보낼 데이터가 없다면 DatagramChannel을 닫기 위해 close()를 사용
datagramChannel.close();
import java.net.InetSocketAddress; import java.net.StandardProtocolFamily; import java.nio.ByteBuffer; import java.nio.channels.DatagramChannel; import java.nio.charset.Charset; public class UdpSendExample { public static void main(String[] args) throws Exception { DatagramChannel datagramChannel = DatagramChannel.open(StandardProtocolFamily.INET);
System.out.println("[발신 시작]");
for(int i=1; i<3; i++) { String data = "메시지" + i; Charset charset = Charset.forName("UTF-8"); ByteBuffer byteBuffer = charset.encode(data);
int byteCount = datagramChannel.send( byteBuffer, new InetSocketAddress("localhost", 5001) ); // 데이터 보내기 System.out.println("[보낸 바이트 수] " + byteCount + " bytes"); }
System.out.println("[발신 종료]");
datagramChannel.close(); }
} |
수신자 :
DatagramChannel 을 이용해 데이터를 받기 위해서는 bind() 를 호출해 먼저 포트와 바인딩을 해야합니다.
DatagramChannel datagramChannel = DatagramChannel.open(StandardProtocalFamily.INET);
포트와 바인딩 후 recieve() 로 데이터를 받을 수 있습니다.
매개 값을 받은 데이터를 저장할 ByteBuffer 이고 리턴 타입은 원격 클라이언트의 IP와 포트 정보를
가지고 있는 SocketAddress 이고 실제는 InetSocketAddress 가 리턴됩니다.
SockeAddress socketAddress = datagramChannel.receive(ByteBuffer dst);
데이터를 받기 전까지 receive() 는 블로킹이 되고, 데이터를 받으면 리턴됩니다.
수신자는 항상 데이터를 받을 준비를 해야합니다.
=> 작업 스레드를 생성해서 receive()를 반복적으로 호출해야 합니다.
작업 스레드 종료 방법
- receive()가 블로킹되어 있는 상태에서 작업 스레드의 interrupt()를 호출하여 ClosedInterruptException 예외를 발생시키거나
- DatagramChannel의 close()를 호출하여 AsynchronousCloseException예외를 발생 시키고
그 후 예외 처리 코드에서 작업 스레드를 종료시키면 됩니다.
datagramChannel.close();
import java.net.InetSocketAddress; import java.net.SocketAddress; import java.net.StandardProtocolFamily; import java.nio.ByteBuffer; import java.nio.channels.DatagramChannel; import java.nio.charset.Charset; public class UdpReceiveExample extends Thread { public static void main(String[] args) throws Exception { DatagramChannel datagramChannel = DatagramChannel.open(StandardProtocolFamily.INET); datagramChannel.bind(new InetSocketAddress(5001));
Thread thread = new Thread() { // 스레드 생성 @Override public void run() { System.out.println("[수신 시작]"); try { while(true) { ByteBuffer byteBuffer = ByteBuffer.allocateDirect(100); SocketAddress socketAddress = datagramChannel.receive(byteBuffer); // 데이터 받기 byteBuffer.flip();
Charset charset = Charset.forName("UTF-8"); String data = charset.decode(byteBuffer).toString(); System.out.println("[받은 내용: " + socketAddress.toString() + "] " + data); } } catch (Exception e) { System.out.println("[수신 종료]"); } } }; thread.start();
Thread.sleep(10000); datagramChannel.close(); }
} |
'자바' 카테고리의 다른 글
자바 SecureRandom 클래스를 이용한 인증토큰만들기! (1) | 2018.04.16 |
---|---|
자바 배열에서 [] 와 ... 의 차이?! (0) | 2018.04.03 |
JSP 메일보내기 jsp 메일 전송 예제 (1) | 2017.05.05 |
자바 NIO 비동기 채널 채팅 클라이언트 만들기 (0) | 2017.05.04 |
자바 NIO 비동기 채널 채팅 서버 만들기 (0) | 2017.05.04 |