java NIO selector ServerSocketChannel 例子

来源:互联网 发布:java短信验证码第三方 编辑:程序博客网 时间:2024/05/21 09:54

1、概述
Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件。这样,一个单独的线程可以管理多个channel,从而管理多个网络连接。
Java NIO中的 ServerSocketChannel 是一个可以监听新进来的TCP连接的通道, 就像标准IO中的ServerSocket一样。

2、例子
例子的思路,初始化ServerSocketChannel ,将ServerSocketChannel 注册到Selector,Selector监听ServerSocketChannel的accept事件,由ServerSocketChannel accept而产生的SocketChannel,再将SocketChannel的read事件注册到Selector。

import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.ServerSocketChannel;import java.nio.channels.SocketChannel;import java.util.Iterator;public class MyNioServer {    private Selector selector;    public static void main(String[] args){        new MyNioServer().start();    }    //初始化类    public void start(){        try {            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();            serverSocketChannel.configureBlocking(false);            serverSocketChannel.socket().bind(new InetSocketAddress(9999));            selector = Selector.open();            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);            //循环等待服务            while(true){                //至少有一个channel准备就绪                selector.select();                //channel状态遍历                Iterator<?> it = selector.selectedKeys().iterator();                while (it.hasNext()){                    SelectionKey key =(SelectionKey) it.next();                    if(key.isReadable()){                        readData(key);                    }else if(key.isAcceptable()){                        connectEven(key);                    }                    it.remove();                }            }        } catch (IOException e) {            e.printStackTrace();        }    }    //连接处理    public void connectEven(SelectionKey key){        try {            ServerSocketChannel server = (ServerSocketChannel)key.channel();            SocketChannel channel = server.accept();            channel.configureBlocking(false);            //获得远程连接的IP地址            System.out.println("已有连接,连接的ip地址是"+ channel.socket().getInetAddress());            channel.register(selector,SelectionKey.OP_READ);        } catch (IOException e) {            e.printStackTrace();        }    }    //数据读取处理    public void readData(SelectionKey key){        SocketChannel socketChannel = (SocketChannel) key.channel();        ByteBuffer buf = ByteBuffer.allocate(1024);        try {            int readSize = socketChannel.read(buf);            if(readSize>0){                byte[] data = buf.array();                String msg = new String(data,"UTF-8").trim();                System.out.println(msg);            }        } catch (IOException e) {            e.printStackTrace();        }    }}

使用网络助手调试,调试结果如图:
这里写图片描述

原创粉丝点击