netty socketchannel,netty作为客户端与普通socket服务端

  netty socketchannel,netty作为客户端与普通socket服务端

  

目录

NioSocketChannel的创建回到上一小节的阅读()方法我们首先看readBufjdk底层相关的内容跟到父类构造方法中我们跟进其构造方法前文传送门:Netty客户端处理接入事件处理创建

 

  

NioSocketChannel的创建

 

  

回到上一小节的read()方法

public void read() { //必须是NioEventLoop方法调用的,不能通过外部线程调用断言事件循环().inEventLoop();//服务端引导的config最终通道配置config=config();//服务端引导的管道最终通道管道管道=管道();//处理服务端接入的速率最终RecvByteBufAllocator .Handle allocHandle=unsafe().recvBufAllocHandle();//设置配置allocHandle.reset(配置);布尔闭合=假;可投掷的异常=空尝试{尝试{ do { //创建爪哇岛开发工具包底层的通道//readBuf用于临时承载读到链接int localRead=doReadMessages(read buf);if(local read==0){ break;} if(本地读取0){ closed=true;打破;} //分配器将读到的链接进行计数阿洛钱德尔。incmessagesread(localRead);//连接数是否超过最大值} while(allochandle。继续阅读());} catch(Throwable t){ exception=t;} int size=read buf。size();//遍历每一条客户端连接for(int I=0;我尺寸;I){ read pending=false;//传递事件,将创建尼奥索凯频道进行传递//最终会调用服务器引导的内部类ServerBootstrapAcceptor的通道读取()方法管道。firechannelread(读取buf。get(I));}读buf。clear();阿洛钱德尔。读取完成();管道。firechannelreadcomplete();//代码省略}最后{ //代码省略}}我们继续剖析int localRead=doReadMessages(read buf)这一部分逻辑

 

  

我们首先看readBuf

private final ListObject readBuf=new ArrayListObject();这里只是简单的定义了一个数组列表,doReadMessages(readBuf)方法就是将读到的链接放在这个目录中,因为这里是NioServerSocketChannel所以这走到了NioServerSocketChannel的doReadMessage()方法

 

  跟到doReadMessage()方法中:

  受保护的int doread messages(ListObject buf)引发异常{ //根据当前爪哇岛开发工具包底层的s

  erverSocketChannel拿到jdk底层channel SocketChannel ch = javaChannel().accept(); try { if (ch != null) { //封装成一个NioSokectChannel扔到buf中 buf.add(new NioSocketChannel(this, ch)); return 1; } } catch (Throwable t) { //代码省略 } return 0;}

 

  

jdk底层相关的内容

首先根据jdk的ServerSocketChannel拿到jdk的Channel, 熟悉Nio的小伙伴应该不会陌生

 

  封装成一个NioSokectChannel扔到Readbuf中

  这里的NioSocketChannel是对jdk底层的SocketChannel的包装, 我们看到其构造方法传入两个参数, this代表当前NioServerSocketChannel, ch代表jdk的SocketChannel

  我们跟到NioSocketChannel的构造方法中:

  

public NioSocketChannel(Channel parent, SocketChannel socket) { super(parent, socket); config = new NioSocketChannelConfig(this, socket.socket());}

这里看到调用了父类构造方法, 传入两个参数, parent代表创建自身channel的, NioServerSocketChannel, socket代表jdk底层的socketChannel

 

  

 

  

跟到父类构造方法中

protected AbstractNioByteChannel(Channel parent, SelectableChannel ch) { super(parent, ch, SelectionKey.OP_READ);}

其中SelectionKey.OP_READ代表其监听事件是读事件

 

  继续跟父类的构造方法:

  

protected AbstractNioChannel(Channel parent, SelectableChannel ch, int readInterestOp) { super(parent); this.ch = ch; this.readInterestOp = readInterestOp; try { //设置为非阻塞 ch.configureBlocking(false); } catch (IOException e) { //代码省略 }}

这里初始化了自身成员变量ch, 就是jdk底层的SocketChannel, 并初始化了自身的监听事件readInterestOp, 也就是读事件

 

  ch.configureBlocking(false)这一步熟悉nio的小伙伴也不陌生, 就是将jdk的SocketChannel设置为非阻塞

  我们继续跟到父类构造方法中:

  

protected AbstractChannel(Channel parent) { this.parent = parent; id = newId(); unsafe = newUnsafe(); pipeline = newChannelPipeline();}

这里初始化parent, 也就是创建自身的NioServerSocketChannel, 并为自身创建了唯一id

 

  初始化unsafe, 我们跟到newUnsafe()方法中

  由于此方法是NioEventLoop调用的, 所以会走到其父类AbstractNioByteChannel的newUnsafe()

  跟到newUnsafe()中:

  

protected AbstractNioUnsafe newUnsafe() { return new NioByteUnsafe();}

这里创建了NioByteUnsafe对象, 所以NioSocketChannel对应的unsafe是NioByteUnsafe

 

  继续往下跟, 我们看到其初始化了pipeline, 有关pipline的知识, 我们会在下一章节中讲到

  回到NioSocketChannel中的构造方法:

  

public NioSocketChannel(Channel parent, SocketChannel socket) { super(parent, socket); config = new NioSocketChannelConfig(this, socket.socket());}

同NioServerSocketChannel一样, 这里也初始化了一个Config属性, 传入两个参数, 当前NioSocketChannel自身和jdk的底层SocketChannel的socket对象

 

  

 

  

我们跟进其构造方法

private NioSocketChannelConfig(NioSocketChannel channel, Socket javaSocket) { super(channel, javaSocket);}

同样, 这个类是NioSocketChannel的内部类

 

  继续跟父类构造方法:

  

public DefaultSocketChannelConfig(SocketChannel channel, Socket javaSocket) { super(channel); if (javaSocket == null) { throw new NullPointerException("javaSocket"); } //保存当前javaSocket this.javaSocket = javaSocket; //是否禁止Nagle算法 if (PlatformDependent.canEnableTcpNoDelayByDefault()) { try { setTcpNoDelay(true); } catch (Exception e) { } }}

这里保存了SocketChannel的socket对象, 并且默认的情况禁止了Nagle算法, 有关Nagle, 感兴趣的同学可以学习下相关知识

 

  继续跟到父类构造方法中:

  

public DefaultChannelConfig(Channel channel) { this(channel, new AdaptiveRecvByteBufAllocator());}

又跟到到了我们熟悉的部分了, 也就是说, 无论NioServerSocketChannel和NioSocketChannel, 最后都会初始化DefaultChannelConfig, 并创建可变ByteBuf分配器, 我们之前小节对此做过详细剖析这里不再赘述, 这部分忘记的内容可以阅读之前小节内容进行回顾

 

  这个分配器什么时候真正分配字节缓冲的呢?我们会在之后的章节进行详细剖析

  至此我们剖析完成了NioSocketChannel的初始化过程

  以上就是Netty客户端接入流程NioSocketChannel创建源码解析的详细内容,更多关于Netty客户端接入流程NioSocketChannel的资料请关注盛行IT其它相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: