Netty5最简单的例子WritingaDiscardServer netty discard
源代码自带的全部的example代码都可以在官方下载的压缩文件 netty-5.0.0.Alpha1.tar.bz2中找到,解压该文件后,jar 目录中的 netty-example-5.0.0.Alpha1-sources.jar作为普通压缩文件解压即可看到源代码。
类的说明ionettyexamplediscard 中能找到4个类
DiscardClient.java -- 客户端入口DiscardClientHandler.java -- 客户端 handle
DiscardServer.java -- 服务器入口DiscardServerHandler.java -- 服务器 handle
测试当然,你可以将源代码编译成JAR文件后,用BAT文件去驱动它,创建客户端,然后连接服务器。为了更看清楚,服务器这里可以直接在ECLIPSE里运行,这样,客户端一连上,就能在服务器端输出些什么到控制台或日志文件中,以确认服务器端真的生效了
可是,有2个问题1 能否有更简单的客户端来测试2 现有的服务器代码可是啥都没干,我怎么知道它是正常工作了
简易客户端事实上,你可以用WINDOWS里自带的telnet来连接。不过,WIN7默认不开启telnet服务,你需要手动去开启它,这个搜BAIDU可以教会你,我们就不说了。telnet服务开启后,WIN7中“开始”上的输入栏,输入cmd,打开的窗口中输入命令telnet 127.0.0.1 8089注:我的服务器端在本机,所以地址是 127.0.0.1,开启的端口号是 8089
服务器代码的简单修改官方文档上说在你的 DiscardServerHandler 中这么写
@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg){ ByteBuf in = (ByteBuf)msg; try { while (in.isReadable()) { // (1) System.out.print((char) in.readByte()); System.out.flush(); } } finally { ReferenceCountUtil.release(msg); // (2) }}
问题是,我们看到的代码@Overridepublic void messageReceived(ChannelHandlerContext ctx, Objectmsg) throws Exception { // discard}
方法名不同,估计是不同版本的代码吧,假设我们这么改@Overridepublic void messageReceived(ChannelHandlerContext ctx, Objectmsg) throws Exception { ByteBuf in = (ByteBuf)msg; try { while (in.isReadable()) { // (1) System.out.print((char) in.readByte()); System.out.flush(); } } finally { ReferenceCountUtil.release(msg); // (2) }}
嗯,会报错,象这样:五月 23, 2014 5:30:05 下午io.netty.example.discard.DiscardServerHandlerexceptionCaught警告: Unexpected exception fromdownstream.io.netty.util.IllegalReferenceCountException: refCnt: 0,decrement: 1atio.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:115)atio.netty.buffer.WrappedByteBuf.release(WrappedByteBuf.java:819)atio.netty.buffer.SimpleLeakAwareByteBuf.release(SimpleLeakAwareByteBuf.java:34)atio.netty.util.ReferenceCountUtil.release(ReferenceCountUtil.java:68)atio.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:110)atio.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:74)atio.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:138)atio.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:320)atio.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:846)atio.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:127)atio.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:485)atio.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:452)atio.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:346)atio.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:794)atjava.lang.Thread.run(Thread.java:744)
查了一下,这是因为现在的版本,你不用写这句了:ReferenceCountUtil.release(msg);框架自己帮你做了,你再写这句就会触发这个错误。
所以最后,大概这个方法是这样:@Overridepublic void messageReceived(ChannelHandlerContext ctx, Objectmsg) throws Exception { ByteBuf in =(ByteBuf) msg; while (in.isReadable()) { // (1) System.out.print((char)in.readByte()); System.out.flush(); }}
这样,你输入什么,就能在服务器端输出什么了。。。
关于TCP和UDPsocket可以基于TCP,也可以基于UDP。区别在于UDP的不保证数据包都正确收到,所以性能更好,但容错不高。TCP保证不错,所以性能没那么好。UDP基本只适合做在线视频传输之类,我们的需求应该会是TCP。
那这2种方式在写法上有什么不同?网上搜到这样的说法:
在ChannelFactory 的选择上,UDP的通信选择NioDatagramChannelFactory,TCP的通信我们选择的是NioServerSocketChannelFactory;在Bootstrap的选择上,UDP选择的是ConnectionlessBootstrap,而TCP选择的是ServerBootstrap。
对于编解码器decoder和Encoder,以及ChannelPipelineFactory,UDP开发与TCP并没有什么区别,在此不做详细介绍。
对于ChannelHandler,是UDP与TCP区别的核心所在。大家都知道UDP是无连接的,也就是说你通过MessageEvent 参数对象的 getChannel() 方法获取当前会话连接,但是其 isConnected() 永远都返回false。UDP 开发中在消息获取事件回调方法中,获取了当前会话连接 channel 对象后可直接通过 channel 的write 方法发送数据给对端 channel.write(message,remoteAddress),第一个参数仍然是要发送的消息对象,第二个参数则是要发送的对端 SocketAddress地址对象。这里最需要注意的一点是SocketAddress,在TCP通信中我们可以通过channel.getRemoteAddress()获得,但在UDP通信中,我们必须从MessageEvent中通过调用getRemoteAddress()方法获得对端的SocketAddress地址。
因此按这个说法看,我们这个例子就是基于TCP的。
更多阅读
如何用最简单的方法卸载冰点还原精灵 冰点还原精灵怎么卸载
如何用最简单的方法卸载冰点还原精灵——简介如何用最简单的方法卸载冰点还原精灵,平时用它很方便,但是卸载却有很多人不知道。如何用最简单的方法卸载冰点还原精灵——工具/原料冰点还原精灵如何用最简单的方法卸载冰点还原精灵—
最简单的丰胸方法 最简单有效的丰胸方法
最简单的丰胸方法——简介最简单的丰胸方法?想不想让你的胸部悄悄改变?在不经意间偷偷变大?只要每天睡前或洗澡的时候坚持做做这些“美胸操”,改变,不只是一点点哦。最简单的丰胸方法——方法/步骤最
最简单的减肥方法 最好最简单减肥方法
最简单的减肥方法就是、、、走路!!走路也可以减肥?是的,这不是危言耸听,专家指出,只要用对方法,在走路的时候,掌握以下七个关键点就可以轻松减肥。这可是有科学依据的哦。最简单的减肥方法——步骤/方法最简单的减肥方法 1、走速7级 如果你
用最简单的方法剪五角星和花 五角星的剪法步骤视频
用最简单的方法剪五角星和花——简介用最简单的方法剪五角星和花用最简单的方法剪五角星和花——工具/原料纸剪刀用最简单的方法剪五角星和花——方法/步骤用最简单的方法剪五角星和花 1、备注一张纸,在对折.后在折四下用最简单的
PS.制作最简单的动态图片!!! 精 ps制作动态图
大家可能经常在网上会看到一些动态的图片,从一个位置移动到另一个位置,那么接下来我就教大家制作最简单的动态图片,我教的这个很简单,目的是抛砖引玉!PS.制作最简单的动态图片!!! 精——工具/原料PS软件PS.制作最简单的动态图片!!! 精——步骤/