av一区二区在线观看_亚洲男人的天堂网站_日韩亚洲视频_在线成人免费_欧美日韩精品免费观看视频_久草视

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

java - 使用Netty Demo報(bào)錯(cuò)

瀏覽:90日期:2023-12-24 15:20:14

問(wèn)題描述

public class TimeServer { public void bind(int port) {try { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workGroup = new NioEventLoopGroup(); ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 1024) .childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel arg0) throws Exception { System.out.println('初始化'); arg0.pipeline().addLast(new TimeHandler());} }); ChannelFuture future = b.bind(port).sync(); System.out.println('執(zhí)行這里'); future.channel().closeFuture().sync(); System.out.println('執(zhí)行這里');} catch (InterruptedException e) { e.printStackTrace();} } public static void main(String[] args) {new TimeServer().bind(10000); }}public class TimeHandler extends ChannelInboundHandlerAdapter {@Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {super.channelRead(ctx, msg); ByteBuf buf=(ByteBuf) msg;////byte[] butfs = buf.array();//報(bào)錯(cuò) System.out.println(buf.readableBytes());byte[] butfs = new byte[buf.readableBytes()];buf.readBytes(butfs);System.out.println(new String(butfs,'UTF-8'));System.out.println(msg); }}

客戶端使用的是BIO的模型:

public static void main(String[] args) throws Exception {final int port = 10000;//NioServer server = new NioServer(port);//server.init();/// ========================================================// 接下來(lái)模擬3個(gè)Client并發(fā)訪問(wèn)服務(wù)器int poolsize = 1;ExecutorService pool = Executors.newFixedThreadPool(poolsize);Collection<Callable> tasks = new ArrayList<Callable>(10);final String clientname = 'clientThread';for (int i = 0; i < poolsize; i++) { final int n = i; // 若每一個(gè)Client都保持使用BIO方式發(fā)送數(shù)據(jù)到Server,并讀取數(shù)據(jù)。 tasks.add(new Callable() {@Overridepublic Object call() throws Exception { Socket socket = new Socket('127.0.0.1', port); final InputStream input = socket.getInputStream(); final OutputStream out = socket.getOutputStream(); final String clientname_n = clientname + '_' + n; // BIO讀取數(shù)據(jù)線程 new Thread(clientname_n + '_read') {@Overridepublic void run() { byte[] bs = new byte[1024]; while (true) {try { Thread.sleep(1000);} catch (InterruptedException e) { e.printStackTrace();}int len = 0;try { while ((len = input.read(bs)) != -1) {System.out.println('Clinet thread ' + Thread.currentThread().getName()+ ' read: ' + new String(bs, 0, len)); }} catch (IOException e) { e.printStackTrace();} }} }.start(); // BIO寫數(shù)據(jù)線程 new Thread(clientname_n + '_write') {@Overridepublic void run() { int a = 0; while (true) {try { Thread.sleep(100);} catch (InterruptedException e) { e.printStackTrace();}String str = Thread.currentThread().getName() + ' hello, ' + a;try { out.write(str.getBytes()); out.flush(); a++;} catch (IOException e) { e.printStackTrace();} }} }.start(); return null;} });}pool.invokeAll((Collection<? extends Callable<Object>>) tasks);//server.go(); }

結(jié)果運(yùn)行的時(shí)候出現(xiàn)了以下錯(cuò)誤:

月 13, 2017 5:52:56 下午 io.netty.channel.DefaultChannelPipeline onUnhandledInboundException警告: An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.io.netty.util.IllegalReferenceCountException: refCnt: 0 at io.netty.buffer.AbstractByteBuf.ensureAccessible(AbstractByteBuf.java:1408) at io.netty.buffer.AbstractByteBuf.checkReadableBytes0(AbstractByteBuf.java:1394) at io.netty.buffer.AbstractByteBuf.checkReadableBytes(AbstractByteBuf.java:1383) at io.netty.buffer.AbstractByteBuf.readBytes(AbstractByteBuf.java:850) at io.netty.buffer.AbstractByteBuf.readBytes(AbstractByteBuf.java:858) at test.netty.TimeHandler.channelRead(TimeHandler.java:17) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926) at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134) at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:624) at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:559) at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:476) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:438) at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858) at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144) at java.lang.Thread.run(Thread.java:745)

請(qǐng)問(wèn)這是為什么呢?

問(wèn)題解答

回答1:

在netty4中,對(duì)象的生命周期由引用計(jì)數(shù)器控制,ByteBuf就是如此,每個(gè)對(duì)象的初始化引用計(jì)數(shù)為1,調(diào)用一次release方法,引用計(jì)數(shù)器會(huì)減1,當(dāng)嘗試訪問(wèn)計(jì)數(shù)器為0的,對(duì)象時(shí),會(huì)拋出IllegalReferenceCountException,正如ensureAccessible的實(shí)現(xiàn),更加詳細(xì)的解釋可以參考官方文檔

AbstractByteBuf.java

protected final void ensureAccessible() {if (refCnt() == 0) { throw new IllegalReferenceCountException(0);} }

注意TZ的TimeHandler類中的 super.channelRead(ctx, msg);這行代碼。追蹤調(diào)用路徑,

private void invokeChannelRead(Object msg) {try { ((ChannelInboundHandler) handler()).channelRead(this, msg);} catch (Throwable t) { notifyHandlerException(t);} }

最終調(diào)用的代碼是:ReferenceCountUtil.release(msg)

public static boolean release(Object msg) {if (msg instanceof ReferenceCounted) { return ((ReferenceCounted) msg).release();}return false; }

也就是每次super.channelRead(ctx, msg);后,ByteBuf就會(huì)調(diào)用release()方法,計(jì)數(shù)器減一,然后在buf.readBytes(butfs);這行代碼就會(huì)校驗(yàn)ensureAccessible(),計(jì)數(shù)器為0,netty認(rèn)為ByteBuf對(duì)象已經(jīng)釋放,就拋出異常。

解決方案:

去掉TimeHandler中這行代碼 super.channelRead(ctx, msg);ByteBuf對(duì)象誰(shuí)處理誰(shuí)釋放。

回答2:

An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.缺少exceptionCaught(),在在server端最后一個(gè)Handler中增加exceptionCaught()

標(biāo)簽: java
相關(guān)文章:
主站蜘蛛池模板: 99久久精品免费看国产免费软件 | 国精产品一品二品国精在线观看 | 精品国产乱码久久久 | 欧美三级视频在线观看 | 久久这里只有 | 国产在视频一区二区三区吞精 | 一区二区三区欧美在线 | 久久精品久久精品 | 亚洲传媒在线 | 欧美天堂一区 | 国产精品夜夜夜一区二区三区尤 | 日韩在线中文字幕 | 久久久久久久久淑女av国产精品 | 国产精品久久久久久久久免费桃花 | 国产视频中文字幕 | 99热碰| 午夜爱爱网 | 亚洲黄色一区二区三区 | 毛片av免费在线观看 | 爱高潮www亚洲精品 中文字幕免费视频 | 亚洲成人精品久久久 | 久久一区视频 | 91麻豆久久久 | 欧美影院| 国产三级在线观看播放 | 亚洲精视频 | 一二三四av | 欧美精品一区二区在线观看 | 亚洲精品2 | 天天操夜夜拍 | 欧美一级片在线 | 国产午夜精品一区二区三区四区 | 久久久久国产一区二区三区四区 | 欧美婷婷 | 免费麻豆视频 | 97操操 | 国产精品久久欧美久久一区 | 中文欧美日韩 | 中文字幕成人网 | 亚洲精品免费视频 | 国产一区二区在线播放 |