NIO(七) - 非阻塞试UDP通讯

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();
        }
    }
}

上一篇:NIO(一) - Buffer


下一篇:NIO教程笔记