Netty(2)Echo
上节介绍的是discard协议,即不给客户端返回消息。本节主要说下,echo协议,即服务端收到消息后原样返回给客户端。
为了实现此需求,只需要在DiscardServerHandler中重写channelRead()方法,即可。如下:
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf in = (ByteBuf) msg;
log.info("接收并原样返回:{}",in.toString(io.netty.util.CharsetUtil.UTF_8)); ctx.write(msg);//(1)
ctx.flush();//(2)
}
1、ChannelHandlerContext对象提供了很多方法,如:
ctx.read();
ctx.write();
ctx.flust();
ctx.channel();
ctx.pipeline();
ctx.alloc();
ctx.close();
ctx.connect();
ctx.disconnect();
注意,我们这里没有release 接收到的消息,不像discard例子那样。因为,当消息写到物理网络中后,netty才会在自动release。
在channelRead方法内的最后,加入in.release();即
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf in = (ByteBuf) msg;
log.info("接收并原样返回:{}",in.toString(io.netty.util.CharsetUtil.UTF_8)); ctx.write(msg);//(1)
ctx.flush();//(2)
in.release();
}
则报异常:io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1
因此,不能在server端的channelRead方法内加入in.release()。
当ctx.flush(msg)后,可以在channelReadComplete()方法中release。
2、ctx.write(object)并不会将消息写到物理网络中,而是在内部buffer中的,需要使用ctx.flush()来写入到物理网络中。当然,也可以使用ctx.writeAndFlush(msg)代替。
-----telnet测试:
客户端:
[root@cent7-zuoys ~]# telnet 10.134.253.10 8080
Trying 10.134.253.10...
Connected to 10.134.253.10.
Escape character is '^]'.
遥远2
遥远2
服务端:16:22:12.636 [nioEventLoopGroup-3-1] 接收并原样返回:遥远2
-----client测试:
@Slf4j
public class EchoClientHandler extends SimpleChannelInboundHandler<Object> {
private ByteBuf content;
private ChannelHandlerContext ctx; @Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
this.ctx = ctx;
//content = ctx.alloc().directBuffer(EchoClient.SIZE).writeZero(EchoClient.SIZE);
content = ctx.alloc().directBuffer(EchoClient.SIZE).writeBytes("遥远2".getBytes(CharsetUtil.UTF_8));
//发送以上消息
generatTraffic();
} @Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
content.release();
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf in = (ByteBuf) msg;
log.info("接收消息:{}",in.toString(io.netty.util.CharsetUtil.UTF_8));
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
//*************************自定义方法
private void generatTraffic() {
//flush the outbound buffer to the socket.
//once flushed,generate the same amount of traffic again.
ByteBuf buf = content.retainedDuplicate();
ctx.writeAndFlush(buf).addListener(trafficGenerator);
//Console.log((char)buf.readByte());
log.info("发送消息:{}",buf.toString(io.netty.util.CharsetUtil.UTF_8));
}
private final ChannelFutureListener trafficGenerator = new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()) {
log.info("success!");
} else {
future.cause().printStackTrace();
future.channel().close();
}
}
};
}
红字部分,为修改的。在channelRead0方法中,之前是空的,现在是因为,服务端返回消息了,需要在此处接收。
运行结果:
客户端:
16:50:42.443 [nioEventLoopGroup-2-1] success!
16:50:42.446 [nioEventLoopGroup-2-1] 发送消息:遥远2
16:50:42.461 [nioEventLoopGroup-2-1] 接收消息:遥远2
服务端:16:50:42.456 [nioEventLoopGroup-3-1] 接收并原样返回:遥远2
SimpleChannelInboundHandler 与 ChannelInboundHandlerAdapter区别:
服务端使用ChannelInboundHandlerAdapter,客户端使用SimpleChannelInboundHandler 。
因为ChannelInboundHandlerAdapter,在channelRead()内不能release。而SimpleChannelInboundHandler 自动release。
Netty(2)Echo的更多相关文章
- netty写Echo Server & Client完整步骤教程(图文)
1.创建Maven工程 1.1 父节点的pom.xml代码(root pom文件) 1 <?xml version="1.0" encoding="UTF-8&qu ...
- Java Netty 4.x 用户指南
问题 今天,我们使用通用的应用程序或者类库来实现互相通讯,比如,我们经常使用一个 HTTP 客户端库来从 web 服务器上获取信息,或者通过 web 服务来执行一个远程的调用. 然而,有时候一个通用的 ...
- netty Getting Started--reference
reference from:http://docs.jboss.org/netty/3.1/guide/html/start.html 1.1. Before Getting Started 1.2 ...
- Netty In Action中国版 - 第二章:第一Netty程序
本章介绍 获得Netty4最新的版本号 设置执行环境,以构建和执行netty程序 创建一个基于Netty的server和client 拦截和处理异常 编制和执行Nettyserver和client 本 ...
- Netty 启动过程源码分析 (本文超长慎读)(基于4.1.23)
前言 作为一个 Java 程序员,必须知道Java社区最强网络框架-------Netty,且必须看过源码,才能说是了解这个框架,否则都是无稽之谈.今天楼主不会讲什么理论和概念,而是使用debug 的 ...
- User guide for Netty 4.x
Table of Contents Preface The Solution Getting Started Before Getting Started Writing a Discard Serv ...
- Netty 介绍
本指南对Netty 进行了介绍并指出其意义所在. 1. 问题 现在,我们使用适合一般用途的应用或组件来和彼此通信.例如,我们常常使用一个HTTP客户端从远程服务器获取信息或者通过web service ...
- Netty官方示例
一.DEMO 官方并没有使用Hello World来作为一个例子,而是采用RFC的DISCARD,这个协议定义了就是接收到请求后什么也不干. 第一步编写DiscardServerHandler类: p ...
- netty参考
前言 问题 现如今我们使用通用的应用程序或者类库来实现系统之间地互相访问,比如我们经常使用一个HTTP客户端来从web服务器上获取信息,或者通过web service来执行一个远程的调用. 然而,有时 ...
随机推荐
- hdu-5804 Price List(水题)
题目链接: Price List Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/131072 K (Java/Othe ...
- linux 下errno各个值的意义(转) errno.h
strerror(errno):获取errno对应的错误 查看错误代码errno是调试程序的一个重要方法.当linux C api函数发生异常时,一般会将errno变量(需include errno. ...
- PS 滤镜— — 镜头光晕
clc; clear all; close all; addpath('E:\PhotoShop Algortihm\Image Processing\PS Algorithm'); I=imread ...
- BZOJ4278 [ONTAK2015]Tasowanie[后缀数组+贪心]
题目 求两数组归并后的数组最小字典序排列. 嘛,可能本人在贪心这块还是太弱了(或者说什么都弱),如果不知道是字符串题估计也想不起来用sa. 显然看得出归并时字典序小的那个数组先往里面加,这就是要比较两 ...
- bzoj 1731 [Usaco2005 dec]Layout 排队布局——差分约束
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1731 对差分约束理解更深.还发现美妙博客:http://www.cppblog.com/me ...
- DS:架构-1
ylbtech-DS:架构-1 1. 类库返回顶部 1. 2. 2. 引用返回顶部 1. Api-Base\Common\OAuth2Provider\ServiceBase-OAuth2Provid ...
- cocos2dx 3.0 用ClippingNode做游戏的新手引导
转自:http://blog.csdn.net/star530/article/details/20851263 本篇介绍的是用ClippingNode 做游戏的新手引导,额,或者说是做新手引导的一种 ...
- 利用d3js绘出环形百分比环
利用d3js绘出环形百分比环 (function() { var numberData = [{ value : 0.334, text : "33.4%", color : &q ...
- eclipse中如何去除警告:Class is a raw type. References to generic type Class<T> should be parameterized
转自:https://blog.csdn.net/zwr_1022/article/details/78583872 解决前的源代码: public class test {public static ...
- try-catch-finally中return的执行情况
在try中没有异常的情况下try.catch.finally的执行顺序 try--- finally 如果try中有异常,执行顺序是try--- catch --- finally 如果try中没有异 ...