package com.xbb.demo;
import org.junit.Test;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.time.LocalDateTime;
import java.util.Iterator;
/**
* UDP 非阻塞式
*/
public class DatagramDemo {
/**
* 客户端
*/
@Test
public void sendMsg(){
try(
// 创建UDP Channel
DatagramChannel channel = DatagramChannel.open();
){
// 设置非阻塞式
channel.configureBlocking(false);
// 设置缓冲
ByteBuffer buf = ByteBuffer.allocate(1024);
// 要发送的消息
String currentDate = LocalDateTime.now().toString();
String msg = "现在是 : " + currentDate;
// 把消息写入到缓冲
buf.put(msg.getBytes());
// 切换读写模式(缓冲区如果是操作要从读换到写或从写切换到读,必须进行切换)
buf.flip();
// 发送消息,与其他不同的是.这个地方消息是通过send方法来发送的.
channel.send(buf,new InetSocketAddress("127.0.0.1",9999));
// 清空缓冲区
buf.clear();
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 服务端
*/
@Test
public void receMsg(){
try(
// 创建UDP Channel
DatagramChannel channel = DatagramChannel.open().bind(new InetSocketAddress(9999))
){
// 设置非阻塞式
channel.configureBlocking(false);
// 创建选择器
Selector selector = Selector.open();
// 把选择器注册到通道并设置坚挺读操作
channel.register(selector, SelectionKey.OP_READ);
// 检测选择器"准备就绪"的状态
while(selector.select() > 0){
// 获取选择器里面所有的Key
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
// 如果有值
while (iterator.hasNext()){
SelectionKey next = iterator.next();
// 如果读操作已经就绪的话
if (next.isReadable()){
// 创建缓冲区用来接收数据
ByteBuffer buf = ByteBuffer.allocate(1024);
// 接收客户端发来的消息
channel.receive(buf);
// 切换读写模式
buf.flip();
System.out.println(new String(buf.array(),0,buf.limit()));
// 清空缓冲区
buf.clear();
}
}
iterator.remove();
}
}catch (Exception e){
e.printStackTrace();
}
}
}