netty发送和接收数据handler处理器
netty发送和接收数据handler处理器 主要是继承 SimpleChannelInboundHandler 和 ChannelInboundHandlerAdapter
一般用netty来发送和接收数据都会继承SimpleChannelInboundHandler和ChannelInboundHandlerAdapter这两个抽象类,那么这两个到底有什么区别呢?
其实用这两个抽象类是有讲究的,在客户端的业务Handler继承的是SimpleChannelInboundHandler,而在服务器端继承的是ChannelInboundHandlerAdapter。
最主要的区别就是SimpleChannelInboundHandler在接收到数据后会自动release掉数据占用的Bytebuffer资源(自动调用Bytebuffer.release())。而为何服务器端不能用呢,因为我们想让服务器把客户端请求的数据发送回去,而服务器端有可能在channelRead方法返回前还没有写完数据,因此不能让它自动release。
handler处理器 内置 方法
channelActive
通道激活时触发,当客户端connect成功后,服务端就会接收到这个事件,从而可以把客户端的Channel记录下来,供后面复用
channelRead
这个必须用啊,当收到对方发来的数据后,就会触发,参数msg就是发来的信息,可以是基础类型,也可以是序列化的复杂对象。
channelReadComplete
channelRead执行后触发
exceptionCaught
出错是会触发,做一些错误处理
继承 ChannelInboundHandlerAdapter 具体的例子

/**
* netty服务器的监听 处理器
*
* @author flm 2017年10月27日
*/
public class IOHandler extends ChannelInboundHandlerAdapter { private static Logger log = Logger.getLogger(IOHandler.class); //netty AttributeKey 相对于 web session【重要】
public static final AttributeKey<DeviceSession> KEY = AttributeKey.valueOf("IO"); private Producer producer; public IOHandler(Producer producer){
this.producer=producer;
} /**
* 读取数据
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { DeviceSession session = ctx.channel().attr(KEY).get(); // 检测是否 自己注册的 客户端 ByteBuf buffer=(ByteBuf) msg; if (buffer == null||session == null) {
closeConnection(ctx); // 关闭连接
} MsgEntity msgEntity = new MsgEntity(buffer); // 解码 buffer 封装 msgEntity
log.info("# Accept Client data :"+msgEntity.toString()); if (MsgType.UNKNOW == msgEntity.getMsgType()) {
log.info("# 客户端 发送数据 类型未定义... :"+msgEntity.toString());
return;
} if(!session.isActivity()){
session.setActivity(true);
session.setImei(msgEntity.getImei());
SessionManager.getSingleton().addClient(session);
}
producer.putData(msgEntity); } /**
* 客户端 注册
*/
@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
super.channelRegistered(ctx); log.info(String.format("# client registered...: %s ...", ctx.channel())); DeviceSession session = new DeviceSession(ctx.channel());
// 绑定客户端到SOCKET
ctx.channel().attr(KEY).set(session);
} /**
* 客户端 失去连接
*/
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception
{
super.channelInactive(ctx); log.info(String.format("# client out... : %s", ctx.channel()));
DeviceSession session = ctx.channel().attr(KEY).getAndSet(null); // 移除 session 并删除 该客户端
SessionManager.getSingleton().removeClient(session, true); if(session.getDeviceID() != null)
{
// producer.onData(new Request(new RootMessage(MessageType.LOGOUT, null, null), session));
} } /**
* 心跳机制 用户事件触发
*/
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception
{
if (evt instanceof IdleStateEvent)
{
IdleStateEvent e = (IdleStateEvent) evt; //检测 是否 这段时间没有和服务器联系
if (e.state() == IdleState.ALL_IDLE)
{
//检测心跳
checkIdle(ctx);
}
} super.userEventTriggered(ctx, evt);
} /**
* 报错 处理事件
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception { log.error("# 客户端连接 Netty 出错...");
cause.printStackTrace();
//关闭连接
closeConnection(ctx);
}

netty发送和接收数据handler处理器的更多相关文章
- Netty——高级发送和接收数据handler处理器
netty发送和接收数据handler处理器 主要是继承 SimpleChannelInboundHandler 和 ChannelInboundHandlerAdapter 一般用netty来发送和 ...
- 手把手教你Android手机与BLE终端通信--连接,发送和接收数据
假设你还没有看上一篇 手把手教你Android手机与BLE终端通信--搜索,你就先看看吧,由于这一篇要接着讲搜索到蓝牙后的连接.和连接后的发送和接收数据. 评论里有非常多人问假设一条信息特别长,怎么不 ...
- [Socket网络编程]由于套接字没有连接并且(当使用一个 sendto 调用发送数据报套接字时)没有提供地址,发送或接收数据的请求没有被接受。
原文地址:http://blog.sina.com.cn/s/blog_70bf579801017ylu.html,记录在此方便查看 解决办法: MSDN的说明: Close 方法可关闭远程主机连接, ...
- udp网络程序-发送、接收数据
1. udp网络程序-发送数据 创建一个基于udp的网络程序流程很简单,具体步骤如下: 创建客户端套接字 发送/接收数据 关闭套接字 代码如下: #coding=utf-8from socket im ...
- socket 错误之:OSError: [WinError 10057] 由于套接字没有连接并且(当使用一个 sendto 调用发送数据报套接字时)没有提供地址,发送或接收数据的请求没有被接受。
出错的代码 #server端 import socket import struct sk=socket.socket() sk.bind(('127.0.0.1',8080)) sk.listen( ...
- TCP程序中发送和接收数据
这里我们来探讨一下在网络编程过程中,有关read/write 或者send/recv的使用细节.这里有关常用的阻塞/非阻塞的解释在网上有很多很好的例子,这里就不说了,还有errno ==EAGAIN ...
- MPTCP 源码分析(四) 发送和接收数据
简述: MPTCP在发送数据方面和TCP的区别是可以从多条路径中选择一条 路径来发送数据.MPTCP在接收数据方面与TCP的区别是子路径对无序包 进行重排后,MPTCP的mpcb需要多所有子 ...
- 31.用python中的serial向串口发送和接收数据(案例一)
代码功能说明:1.向串口助手发送十六进制数据:0X01,0X03,0X00,0X00,0X00,0X01,0X84,0X0A: 2.用串口助手向代码发送数据,并将发送过来的数据保存在数据库中,按数据和 ...
- java-TCP协议发送和接收数据
TCP协议接收数据的步骤: A:创建接收数据的Socket对象 创建对象的时候要指定端口 B:监听客户端连接 等待客户端连接 C:获取Socket对象的输入流(字节流) D:读数据,并显示在控制台 E ...
随机推荐
- 视口(viewport)原理详解之第一部分
在这篇文章中,我将解释viewports和元素width是如何工作的,比如html元素. window和 screen. 这篇文章主要针对桌面浏览器,但它的部分和移动设备中的结论也比较类似,所以也是 ...
- Oracle 数据库实例
Oracle- 数据库的实例,表空间,用户,表之间的关系 一.完整的Oracle数据库通常由两部分组成:Oracle数据库和数据库实例 1.数据库是一些列物理文件的集合(数据文件,控制文件,联机文件, ...
- jieba分词加入特殊字符和空格
将原始jieba字典中的空格更改为 @@ 1.原来:雅不可攀 3 nr 2.现在:雅不可攀@@3@@nr 将自定义用户词典加入的词与词性中间的空格更改为@@ 1.原来:牵连关系 50 n 2.现在:牵 ...
- 开启Apache Server Status
开启Apache Server Status 发布时间:August 1, 2008 分类:Apache <DdZend工具提供下载> <PHP中MD5函数效率> Apache ...
- 笔记五:python字符串
一:学习内容 字符串类型 字符串类型判断 字符串类型互转 字符串小练习 二:字符串类型 1. basestring 在python中和字符串相关的数据类型为:str和unicode,他们都是bases ...
- docker搭建私有registry
搭建docker的私有registry 1. registry简介 Docker在2015年推出了distribution项目,即Docker Registry 2.相比于old registry ...
- [转]数据库中Schema(模式)概念的理解
在学习数据库时,会遇到一个让人迷糊的Schema的概念.实际上,schema就是数据库对象的集合,这个集合包含了各种对象如:表.视图.存储过程.索引等. 如果把database看作是一个仓库,仓库很多 ...
- HTML5的新结构标签
在之前的HTML页面中,大家基本上都是用了Div+CSS的布局方式.而搜索引擎去抓取页面的内容的时候,它只能猜测你的某个Div内的内容是文章内容容器,或者是导航模块的容器,或者是作者介绍的容器等等.也 ...
- 在SQLSERVER中如何检测一个字符串中是否包含另一个字符串
--当charindex返回值大于0时则包含 为0不包含 select CHARINDEX('456','123456') SQL语句使用CHARINDEX函数,来测试一个字符串中是否包含另一个字 ...
- MyBatis和Hibernate的优缺点对比。
Hibernate的优点: 1.hibernate是全自动,hibernate完全可以通过对象关系模型实现对数据库的操作,拥有完整的JavaBean对象与数据库的映射结构来自动生成sql. 2.功能强 ...