Java-NIO服务器基本结构

1. 思路

  • 首先,我们通过一个时序图来看下如何创建一个NIO服务端并启动监听,接收多个客户端的连接,进行消息的异步读写。

0909010.png

public class NioServer
{

public static void main(String[] args)
{
    ServerSocketChannel channel = null;
    Selector selector = null;

    try
    {
        InetSocketAddress address = new InetSocketAddress(8400);
        channel = ServerSocketChannel.open();
        channel.configureBlocking(false);
        channel.socket().bind(address);

        selector = Selector.open();
        channel.register(selector, SelectionKey.OP_ACCEPT);
    } catch (IOException ex)
    {
        System.out.println("Couldn't setup server socket");
        System.out.println(ex.getMessage());
        System.exit(1);
    }

    ListenerThread listener = new ListenerThread(selector);
    listener.start();
}

}


class ListenerThread extends Thread
{
private Selector selector = null;

public ListenerThread(Selector selector)
{
    this.selector = selector;
}

public void run()
{
    while (true)
    {

        try
        {
            while (this.selector.select() > 0)
            {
                Set<SelectionKey> keys = this.selector.selectedKeys();
                Iterator<SelectionKey> iterator = keys.iterator();
                while (iterator.hasNext())
                {
                    SelectionKey key = iterator.next();

                    if (key.isAcceptable())
                    {
                        System.out.println("Accepting connection!");
                        ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
                        SocketChannel channel = serverChannel.accept();
                        channel.configureBlocking(false);
                        channel.register(this.selector, SelectionKey.OP_READ);
                    } else if (key.isReadable())
                    {
                        System.out.println("Accpting command!");
                        SocketChannel channel = (SocketChannel) key.channel();
                        ByteBuffer _buffer = ByteBuffer.allocate(256);
                        channel.read(_buffer);
                        _buffer.flip();
                        Charset charset = Charset.forName("UTF-8");
                        CharsetDecoder decoder = charset.newDecoder();
                        CharBuffer charBuffer = decoder.decode(_buffer);
                        System.out.println(charBuffer.toString());
                        channel.register(this.selector, SelectionKey.OP_WRITE);
                    } else if (key.isWritable())
                    {
                        System.out.println("Sending response!");
                        SocketChannel channel = (SocketChannel) key.channel();
                        channel.write(ByteBuffer.wrap(new String("Hello World\n").getBytes()));
                        channel.register(this.selector, SelectionKey.OP_READ);
                    }
                    iterator.remove();
                }
            }
        } catch (IOException ex)
        {
            System.out.println("Error in poll loop");
            System.out.println(ex.getMessage());
            System.exit(1);
        }
    }
}

}


QQ截图20160704031026.png

  • 在window下,通过telnet 127.0.0.1 8400 即可测试程序的运行过程与结果。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,269评论 19 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,863评论 18 399
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,419评论 11 349
  • /Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home...
    光剑书架上的书阅读 4,005评论 2 8
  • 多态 任何域的访问操作都将有编译器解析,如果某个方法是静态的,它的行为就不具有多态性 java默认对象的销毁顺序与...
    yueyue_projects阅读 1,005评论 0 1