创建非阻塞的Socket服务器<一>
前一篇文章我专门为创建多线程的Socket服务,但是貌似没有很多人来看啊。。汗!不过这
并没有什么,我也是刚刚开始写博客,重要的是把自己的理解记下来防止以后忘了,当然了如
果能给其他的新手一些指引那更好!呵呵。。。不说了直接入正题。来看看我们今天讨论的内
容。
上一篇文章我们讨论了怎么创建多线程的socket服务,里面的demo以及讲解我已经写了出来
如果看了的同志们心里面现在应该都有一些印象了,但是在博客的结尾我也提出了一些问题,
怎么防止阻塞。。。。那么这边博文就是为了解决这个问题的。。。
那么 我们首先来认识一下几个类 和 接口:
ServerSocketChannel:可以说ServerSocket的替代类,支持阻塞通信与非阻塞通信
SocketChannel:Socket的替代类,支持阻塞通信与非阻塞通信
Selector:为ServerSocketChannel监控接受连接就绪事件,为SocketChannel监控连接
就绪、读就绪、写就绪事件
SelectionKey:代表ServerSocketChannel及SocketChannel 向Selector注册事件的
句柄。当一个SelectionKey对象位于Selector对象的selected-keys集合中时,就表示
与这个SelectionKey对象相关的事件发生了。。 以上这些类都是Channel接口的子类
备注:其实我们还要关注一个Buffer 和 Charset类 他们定义了缓冲和字符串与字节的互
相转换。
看到这里已经差不多了解了NIO的30%了。。。。。。。。但是要想真正的了解NIO 这些还远
远不够。
接下来我们来详细的看看:
首先我们得知道,ServerSocketChannel和SocketChannel都是SelectableChannel的
子类,SelectableChannel类以及他的子类都能委托Selector来监控他们可能发生的事情
看一些段伪代码:
Selector selector = Selector.open();ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();SelectionKey selectionKey = serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT);
看一下源码会发现 serverSocketChannel 的 register方法是从父类(SelectableChannel)继承而来的 register(Selector sel, int ops)但是调用的是
register(sel, ops, null);是的,典型的多态!
ServerSocketChannel 和 SocketChannel 他们都有register这个方法。。但是 他们
所关注的事件又不同。在ServerSocketChannel中register的时候只肯能发生一件事情,
也就是他的注册事件只有一件事那就是 OP_ACCEPT,但是 SocketChannel 却不同他可能
发生3个事件OP_CONNECT:客户端和服务端连接就绪事件,表示服务端和客户端已经连接成功
OP_READ:读就绪事件,表示在输入流中有可读的数据,可以执行read操作
OP_WRITE:写就绪时间,表示输出流中有可写的数据,可以执行write操作
另外还有另外的两个方法那就是read 和write只不过read和write需要参数都是
ByteBuffer。
好了,今天就先概括到这里,现在回想一下你对NIO包中类结构的理解,这篇博文只是对NIO
中的一个概括,明天我们将对他们一一讲解!希望对新同学们有帮助,当然了我也是新手!呵
呵。。