netty案例,netty4.1基础入门篇四《NettyServer收发数据》
前言介绍
本章节主要介绍服务端在收到数据后,通过writeAndFlush发送ByteBuf字节码向客户端传输信息。因为我们使用客户端模拟器的编码是GBK格式,所以代码中也需要将字节码转换为GBK,否则会乱码。
开发环境
1、jdk1.8【jdk1.7以下只能部分支持netty】
2、Netty4.1.36.Final【netty3.x 4.x 5每次的变化较大,接口类名也随着变化】
3、telnet 测试【可以现在你的win7机器上测试这个命令,用于链接到服务端的测试命令】
代码示例
1 2 3 4 5 6 7 8 9 10 11 12
| itstack-demo-netty-1-04 └── src ├── main │ └── java │ └── org.itstack.demo.netty.server │ ├── MyChannelInitializer.java │ ├── MyServerHandler.java │ └── NettyServer.java └── test └── java └── org.itstack.demo.netty.test └── ApiTest.java
|
MyChannelInitializer.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
public class MyChannelInitializer extends ChannelInitializer<SocketChannel> {
@Override protected void initChannel(SocketChannel channel) { channel.pipeline().addLast(new LineBasedFrameDecoder(1024)); channel.pipeline().addLast(new StringDecoder(Charset.forName("GBK"))); channel.pipeline().addLast(new MyServerHandler()); }
}
|
MyServerHandler.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
public class MyServerHandler extends ChannelInboundHandlerAdapter {
@Override public void channelActive(ChannelHandlerContext ctx) throws Exception { SocketChannel channel = (SocketChannel) ctx.channel(); System.out.println("链接报告开始"); System.out.println("链接报告信息:有一客户端链接到本服务端"); System.out.println("链接报告IP:" + channel.localAddress().getHostString()); System.out.println("链接报告Port:" + channel.localAddress().getPort()); System.out.println("链接报告完毕"); String str = "通知客户端链接建立成功" + " " + new Date() + " " + channel.localAddress().getHostString() + "\r\n"; ByteBuf buf = Unpooled.buffer(str.getBytes().length); buf.writeBytes(str.getBytes("GBK")); ctx.writeAndFlush(buf); }
@Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { System.out.println("客户端断开链接" + ctx.channel().localAddress().toString()); }
@Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " 接收到消息:" + msg); String str = "服务端收到:" + new Date() + " " + msg + "\r\n"; ByteBuf buf = Unpooled.buffer(str.getBytes().length); buf.writeBytes(str.getBytes("GBK")); ctx.writeAndFlush(buf); }
@Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { ctx.close(); System.out.println("异常信息:\r\n" + cause.getMessage()); }
}
|
NettyServer.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
public class NettyServer {
public static void main(String[] args) { new NettyServer().bing(7397); }
private void bing(int port) { EventLoopGroup parentGroup = new NioEventLoopGroup(); EventLoopGroup childGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(parentGroup, childGroup) .channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 128) .childHandler(new MyChannelInitializer()); ChannelFuture f = b.bind(port).sync(); System.out.println("itstack-demo-netty server start done. {关注公众号:bugstack虫洞栈,获取源码}"); f.channel().closeFuture().sync(); } catch (InterruptedException e) { e.printStackTrace(); } finally { childGroup.shutdownGracefully(); parentGroup.shutdownGracefully(); }
}
}
|
测试结果
启动服务端NettyServer

启动模拟器NetAssist 发送数据测试

执行结果
1 2 3 4 5 6 7 8 9 10 11 12 13
| itstack-demo-netty server start done. {关注公众号:bugstack虫洞栈,获取源码} 链接报告开始 链接报告信息:有一客户端链接到本服务端 链接报告IP:10.13.28.13 链接报告Port:7397 链接报告完毕 2019-08-05 16:03:31 接收到消息:你好,服务端。我是<bugstack虫洞栈>公众号,关注我获取源码。“我的结尾是一个换行符,用于传输半包粘包处理” 2019-08-05 16:03:32 接收到消息:你好,服务端。我是<bugstack虫洞栈>公众号,关注我获取源码。“我的结尾是一个换行符,用于传输半包粘包处理” 2019-08-05 16:03:33 接收到消息:你好,服务端。我是<bugstack虫洞栈>公众号,关注我获取源码。“我的结尾是一个换行符,用于传输半包粘包处理” 2019-08-05 16:03:33 接收到消息:你好,服务端。我是<bugstack虫洞栈>公众号,关注我获取源码。“我的结尾是一个换行符,用于传输半包粘包处理” 客户端断开链接/10.13.28.13:7397
Process finished with exit code -1
|
微信公众号:bugstack虫洞栈,欢迎您的关注&获取源码!
