Java netty之NioServerSocketChannel
来源:互联网 发布:mysql qps 和 tps 编辑:程序博客网 时间:2024/05/16 17:03
在上一篇文章中分析了AbstractNioChannel,那么在这一篇文章中就分析一个具体的NioChannel类。。。
NioServerSocketChannel类用过netty的应该都比较熟悉吧,如果做服务器端的编程,那么我们一般情况下都是使用的这种类型的channel。
按照惯例,我们还是先来分析一下它的继承体系:
NioServerSocketChannel直接继承自AbstractNioMessageChannel,而AbstractNioMessageChannel则直接继承自AbstractNioChannel,
在这里先分析一下AbstractNioMessageChannel:
@Override protected AbstractNioUnsafe newUnsafe() { return new NioMessageUnsafe(); }这个方法比较重要吧,这里就是真正的创建UnSafe对象了,在AbstractNioMessageChannel中定义了NioMessageUnsafe类型,在其中定义具体的read方法:
public void read() { assert eventLoop().inEventLoop(); final SelectionKey key = selectionKey(); //获取select key if (!config().isAutoRead()) { // only remove readInterestOp if needed key.interestOps(key.interestOps() & ~readInterestOp); } final ChannelPipeline pipeline = pipeline(); //获取pipeline final MessageBuf<Object> msgBuf = pipeline.inboundMessageBuffer(); //获取存放读取数据的buffer boolean closed = false; boolean read = false; boolean firedChannelReadSuspended = false; try { for (;;) { int localReadAmount = doReadMessages(msgBuf); //其实还是调用doReadMessages方法来读取数据,并将它保存到buffer当中去 if (localReadAmount > 0) { read = true; } else if (localReadAmount == 0) { break; } else if (localReadAmount < 0) { closed = true; break; } } } catch (Throwable t) { if (read) { read = false; pipeline.fireInboundBufferUpdated(); } if (t instanceof IOException) { closed = true; } else if (!closed) { firedChannelReadSuspended = true; pipeline.fireChannelReadSuspended(); } pipeline().fireExceptionCaught(t); } finally { if (read) { pipeline.fireInboundBufferUpdated(); } if (closed && isOpen()) { close(voidFuture()); } else if (!firedChannelReadSuspended) { pipeline.fireChannelReadSuspended(); } } } }代码还是比较的简单吧,首先先后去selectkey,然后从pipeline中获取用于存读取数据的buffer,最后再调用doReadMessages方法来真正的读取数据,这个方法在当前的AbstractNioMessageChannel中并没有实现,而是留给了以后具体的类。
@Override protected void doFlushMessageBuffer(MessageBuf<Object> buf) throws Exception { final int writeSpinCount = config().getWriteSpinCount() - 1; //总共有多少个buffer需要写 while (!buf.isEmpty()) { boolean wrote = false; for (int i = writeSpinCount; i >= 0; i --) { int localFlushedAmount = doWriteMessages(buf, i == 0); //其实还是调用doWriteMessages方法来发送数据 if (localFlushedAmount > 0) { wrote = true; break; } } if (!wrote) { break; } } }该方法用于写数据,其实最终也是调用doWriteMessages方法来具体的写数据,而这个方法在当前AbstractNioMessageChannel中也并没有实现,也要等到以后实现。。。
好了,接下来分析NioServerSocketChannel类,首先来看它的构造方法:
public NioServerSocketChannel() { //在这里,新创建的ServerSocketChannel就是哪个SlectableChannel了 super(null, null, newSocket(), SelectionKey.OP_ACCEPT); config = new DefaultServerSocketChannelConfig(this, javaChannel().socket()); }这个应该比较简单吧,调用了newSocket方法来创建具体的channel,这是一个类方法,我们来看看它的定义:
private static ServerSocketChannel newSocket() { try { return ServerSocketChannel.open(); //这里就是创建ServerSocketChannel了 } catch (IOException e) { throw new ChannelException( "Failed to open a server socket.", e); } }用过java nio的就应该比较熟悉了,这里是创建一个nio 的serversocketchannel对象,也就是在前面AbstractNioChannel中有提到过的SelectableChannel,另外这该类中实现了doReadMessages方法:
@Override protected int doReadMessages(MessageBuf<Object> buf) throws Exception { //其实serverchannel的读取,无非就是accept函数啊 SocketChannel ch = javaChannel().accept(); try { if (ch != null) { buf.add(new NioSocketChannel(this, null, ch));//将获取的socektchannel放入到buffer当中去 return 1; } } catch (Throwable t) { logger.warn("Failed to create a new channel from an accepted socket.", t); try { ch.close(); } catch (Throwable t2) { logger.warn("Failed to close a socket.", t2); } } return 0; }很简单吧,其实serverchannel读数据不就是accept方法嘛,至于其他的传输数据的方法,向doConnect,write什么的就直接抛出异常就是了,serverchannel怎么能有这些方法呢。。。
好了,NioServerSocketChannel已经分析的差不多了,接下来该分析什么呢,貌似不知道啊。。。应该是NioSocketChannel,pipeline,promise什么的吧。。。。
- Java netty之NioServerSocketChannel
- netty NioServerSocketChannel注册流程一
- java netty之AbstractNioChannel
- java netty之NioSocketChannel
- java netty之ChannelPipeline
- java netty之DefaultChannelHandlerContext
- java netty之DefaultChannelPipeline
- java netty之ChannelInitializer
- java netty之ChannelInboundByteHandlerAdapter
- java netty之ByteToMessageDecoder
- java netty之MessageToByteEncoder
- java netty之ByteToMessageDecoder
- java netty之ChannelInitializer
- netty5.0之server端NioServerSocketChannel的bind分析
- Netty之java序列化
- Netty 之 netty源码学习之大话java NIO
- java netty之ServerBootstrap的启动
- java netty handler之ChannelInboundHander与ChannelOutboundHandler
- Android 按两次返回键退出程序
- 关于VXLAN与异构云之间的集成 ( by quqi99 )
- ext panel 中draggable:true无效
- Observer + onChange 实现video和images的监控
- Struts 源码学习之ActionServlet ( 一)
- Java netty之NioServerSocketChannel
- 高性能服务器架构
- Struts 源码学习之ActionServlet ( 二)
- 【xinfanqie】教你9大方法优化Windows系统内存
- C和C++混合编程中编译器(VS2008)设置
- android学习笔记(八)SharedPreferences、editor
- Android蓝牙打印格式排版
- Portlet知识
- android常用的URI如下