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处理器的更多相关文章

  1. Netty——高级发送和接收数据handler处理器

    netty发送和接收数据handler处理器 主要是继承 SimpleChannelInboundHandler 和 ChannelInboundHandlerAdapter 一般用netty来发送和 ...

  2. 手把手教你Android手机与BLE终端通信--连接,发送和接收数据

    假设你还没有看上一篇 手把手教你Android手机与BLE终端通信--搜索,你就先看看吧,由于这一篇要接着讲搜索到蓝牙后的连接.和连接后的发送和接收数据. 评论里有非常多人问假设一条信息特别长,怎么不 ...

  3. [Socket网络编程]由于套接字没有连接并且(当使用一个 sendto 调用发送数据报套接字时)没有提供地址,发送或接收数据的请求没有被接受。

    原文地址:http://blog.sina.com.cn/s/blog_70bf579801017ylu.html,记录在此方便查看 解决办法: MSDN的说明: Close 方法可关闭远程主机连接, ...

  4. udp网络程序-发送、接收数据

    1. udp网络程序-发送数据 创建一个基于udp的网络程序流程很简单,具体步骤如下: 创建客户端套接字 发送/接收数据 关闭套接字 代码如下: #coding=utf-8from socket im ...

  5. socket 错误之:OSError: [WinError 10057] 由于套接字没有连接并且(当使用一个 sendto 调用发送数据报套接字时)没有提供地址,发送或接收数据的请求没有被接受。

    出错的代码 #server端 import socket import struct sk=socket.socket() sk.bind(('127.0.0.1',8080)) sk.listen( ...

  6. TCP程序中发送和接收数据

    这里我们来探讨一下在网络编程过程中,有关read/write 或者send/recv的使用细节.这里有关常用的阻塞/非阻塞的解释在网上有很多很好的例子,这里就不说了,还有errno ==EAGAIN ...

  7. MPTCP 源码分析(四) 发送和接收数据

    简述:      MPTCP在发送数据方面和TCP的区别是可以从多条路径中选择一条 路径来发送数据.MPTCP在接收数据方面与TCP的区别是子路径对无序包 进行重排后,MPTCP的mpcb需要多所有子 ...

  8. 31.用python中的serial向串口发送和接收数据(案例一)

    代码功能说明:1.向串口助手发送十六进制数据:0X01,0X03,0X00,0X00,0X00,0X01,0X84,0X0A: 2.用串口助手向代码发送数据,并将发送过来的数据保存在数据库中,按数据和 ...

  9. java-TCP协议发送和接收数据

    TCP协议接收数据的步骤: A:创建接收数据的Socket对象 创建对象的时候要指定端口 B:监听客户端连接 等待客户端连接 C:获取Socket对象的输入流(字节流) D:读数据,并显示在控制台 E ...

随机推荐

  1. eclipse 首次使用配置

      这里是eclipse neo版本的配置  1.设置workspace 首次启动,选择指定的工作空间(workspace),用于存放java代码.

  2. 【数组】Search Insert Position

    题目: Given a sorted array and a target value, return the index if the target is found. If not, return ...

  3. fastText 安装

    Windows: https://www.lfd.uci.edu/~gohlke/pythonlibs/#fasttext 下载需要的版本 然后:pip install 文件名

  4. mongodb limit()和skip()

    MongoDB Limit() 方法 如果你需要在MongoDB中读取指定数量的数据记录,可以使用MongoDB的Limit方法,limit()方法接受一个数字参数,该参数指定从MongoDB中读取的 ...

  5. C++中迭代器原理、失效和简单实现

    目录 迭代器的使用 迭代器的种类 迭代器的失效 迭代器的实现 1.迭代器的使用 为了提高C++编程的效率,STL中提供了许多容器,包括vector.list.map.set等.有些容器例如vector ...

  6. redis实战笔记(3)-第3章 Redis命令

    第3章 Redis命令   本章主要内容 字符串命令. 列表命令和集合命令 散列命令和有序集合命令 发布命令与订阅命令 其他命令   在每个不同的数据类型的章节里, 展示的都是该数据类型所独有的. 最 ...

  7. httpSession的正确理解

    关于HttpSession的误解实在是太多了,本来是一个很简单的问题,怎会搞的如此的复杂呢?下面说说我的理解吧: 一个session就是一系列某用户和服务器间的通讯.服务器有能力分辨出不同的用户.一个 ...

  8. Java8新特性--流(Stream)

    1.简介      Java 8是Java自Java 5(发布于2004年)之后的最重要的版本.这个版本包含语言.编译器.库.工具和JVM等方面的十多个新特性.在本文中我们一起来学习引入的一个新特性- ...

  9. eclipse配置tomcat Mac平台

    1.到 apache官方主页 http://tomcat.apache.org 下载 Mac 版本的完整 tar.gz文件包.解压拷贝到 /Library 目录下,并命名为Tomcat,其他目录也可以 ...

  10. 深入理解java虚拟机---4虚拟机类加载机制

    本文来源于翁舒航的博客,点击即可跳转原文观看!!!(被转载或者拷贝走的内容可能缺失图片.视频等原文的内容) 若网站将链接屏蔽,可直接拷贝原文链接到地址栏跳转观看,原文链接:https://www.cn ...