Java NIO UDP发送接收数据

来源:互联网 发布:瘦脸针副作用 知乎 编辑:程序博客网 时间:2024/05/22 13:28
Java的NIO包中,有一个专门用于发送UDP数据包的类:DatagramChannel,UDP是一种无连接的网络协议,一般用于发送一些准确度要求不太高的数据等。

完整的服务端程序如下:

public class StatisticsServer {    //每次发送接收的数据包大小    private final int MAX_BUFF_SIZE = 1024 * 10;    //服务端监听端口,客户端也通过该端口发送数据    private int port;    private DatagramChannel channel;    private Selector selector;    private ScheduledExecutorService es = Executors.newScheduledThreadPool(1);    public void init() throws IOException {        //创建通道和选择器        selector = Selector.open();        channel = DatagramChannel.open();        //设置为非阻塞模式        channel.configureBlocking(false);        channel.socket().bind(new InetSocketAddress(port));        //将通道注册至selector,监听只读消息(此时服务端只能读数据,无法写数据)        channel.register(selector, SelectionKey.OP_READ);        //使用线程的方式,保证服务端持续等待接收客户端数据        es.scheduleWithFixedDelay(new Runnable() {            @Override            public void run() {                try {                    while(selector.select() > 0) {                        Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();                        while(iterator.hasNext()) {                            SelectionKey key = iterator.next();                            try {                                iterator.remove();                                if(key.isReadable()) {                                    //接收数据                                    doReceive(key);                                }                            } catch (Exception e) {                                logger.error("SelectionKey receive exception", e);                                try {                                    if (key != null) {                                        key.cancel();                                        key.channel().close();                                    }                                } catch (ClosedChannelException cex) {                                    logger.error("Close channel exception", cex);                                }                            }                        }                    }                } catch (IOException e) {                    logger.error("selector.select exception", e);                }            }        }, 0L, 2L, TimeUnit.MINUTES);    }    //处理接收到的数据    private void doReceive(SelectionKey key) throws IOException {        String content = "";        DatagramChannel sc = (DatagramChannel) key.channel();        ByteBuffer buffer = ByteBuffer.allocate(MAX_BUFF_SIZE);        buffer.clear();        sc.receive(buffer);        buffer.flip();        while(buffer.hasRemaining()) {            byte[] buf = new byte[buffer.limit()];            buffer.get(buf);            content += new String(buf);        }        buffer.clear();        logger.debug("receive content="+content);        if(StringUtils.isNotBlank(content)) {            doSave(content);        }    } }

客户端发送完整例子如下:

DatagramChannel channel = DatagramChannel.open();        StringBuilder sb = new StringBuilder();        sb.append("2017-03-09 12:30:00;")                .append("aaa")                .append("testapp;")                .append("test.do;")                .append("param=hello;")                .append("test;")                .append("100;")                .append("1");        ByteBuffer buffer = ByteBuffer.allocate(10240);        buffer.clear();        buffer.put(sb.toString().getBytes());        buffer.flip();        //此处IP为服务端IP地址,端口和服务端的端口一致        int n = channel.send(buffer, new InetSocketAddress("127.0.0.1", 8080));        System.out.println(n);        //每次数据发送完毕之后,一定要调用close方法,来关闭占用的udp端口,否则程序不结束,端口不会释放        channel.close();
0 0
原创粉丝点击