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. wp 去除google字体加载

    add_filter('gettext_with_context', 'disable_open_sans', 888, 4 ); function disable_open_sans( $trans ...

  2. Java虚拟机(三):JVM垃圾回收机制

    概述 垃圾收集 Garbage Collection 通常被称为“GC”,它诞生于1960年 MIT 的 Lisp 语言,经过半个多世纪,目前已经十分成熟了. jvm 中,程序计数器.虚拟机栈.本地方 ...

  3. maven私服配置

    1.maven私服setting.xml的配置 <?xml version="1.0" encoding="UTF-8"?> <setting ...

  4. android studio启动和项目编译问题

    第一次安装完成后,不要立刻启动,首先在Android Studio安装目录下的 bin 目录下,找到 idea.properties 文件,在文件最后追加disable.android.first.r ...

  5. select样式

    select设置了宽高: 样式是这样的: 如果在select的标签内部加入size="2"    size的值只要大于1,select的设置大小会起作用 样式是这样的: 3.点击中 ...

  6. SpringMVC源码阅读:核心分发器DispatcherServlet

    1.前言 SpringMVC是目前J2EE平台的主流Web框架,不熟悉的园友可以看SpringMVC源码阅读入门,它交代了SpringMVC的基础知识和源码阅读的技巧 本文将介绍SpringMVC的核 ...

  7. Spring IOC(DI)

    软件152 余建强 1 什么是IOC IOC—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想.在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不 ...

  8. sqlserver中利用Tran_sql把逗号分隔的字符串拆成临时表

    在与数据库交互的过程中,我们经常需要把一串ID组成的字符串当作参数传给存储过程获取数据.很多时候我们希望把这个字符串转成集合以方便用于in操作. 有两种方式可以方便地把这个以某种符号分隔的ID字符串转 ...

  9. [转]File uploads in ASP.NET Core

    本文转自:https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads By Steve Smith ASP.NET MVC ...

  10. C# 数据库增加新表怎么更新ef

    找到dbmx文件,打开,右键,更新模型 也可以 右键从模型中删除 重新更新过来,感觉说了句废话 哈哈