源码下载 -> 提取码  QQ:505645074


Netty 是一个高性能、异步事件驱动的 NIO 框架,它提供了对 TCP、UDP 和文件传输的支持,作为一个异步 NIO 框架,Netty 的所有 IO 操作都是异步非阻塞的,通过 Future-Listener 机制,用户可以方便的主动获取或者通过通知机制获得 IO 操作结果。

作为当前最流行的 NIO 框架,Netty 在互联网领域、大数据分布式计算领域、游戏行业、通信行业等获得了广泛的应用,一些业界著名的开源组件也基于 Netty 的 NIO 框架构建。

协议解析代码:

package nettyserver;

import io.netty.buffer.ByteBuf;

import io.netty.buffer.Unpooled;

import io.netty.channel.ChannelHandlerContext;

import io.netty.channel.ChannelInboundHandlerAdapter;

import io.netty.handler.timeout.IdleStateEvent;

import io.netty.util.ReferenceCountUtil;

import java.util.HashMap;

import java.util.Map;

class MyInHandler extends ChannelInboundHandlerAdapter {

final byte HEAD1 = 0x48;// H

final byte HEAD2 = 0x54;// T

final byte HEAD3 = 0x45;// E

final byte HEAD4 = 0x4D;// M

final byte HEAD5 = 0x50;// P

final byte HEAD6 = 0x3D;// =

public static final String SPLIT1 = "#";

public static Map<String, io.netty.buffer.ByteBuf> dicSn2Buffer = new HashMap<>();

// HTEMP=0026#1533022506#Meter-001#01##

@Override

public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)

{

// 当出现异常就关闭连接

//cause.printStackTrace();

RemoveClient(ctx, "exceptionCaught");

}

@Override

public void channelActive(io.netty.channel.ChannelHandlerContext ctx) throws Exception

{

CTxtHelp.AppendLog("客户端已经连接,sn:" + GetSN(ctx));

}

@Override

public void channelInactive(io.netty.channel.ChannelHandlerContext ctx) throws Exception

{

RemoveClient(ctx, "channelInactive");

}

@Override

public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception

{

if (evt instanceof IdleStateEvent)

{

String type = "未知";

IdleStateEvent event = (IdleStateEvent) evt;

if (null != event.state())

{

switch (event.state())

{

case READER_IDLE: type = "read idle"; break;

case WRITER_IDLE: type = "write idle"; break;

case ALL_IDLE: type = "all idle"; break;

default: break;

}

}

RemoveClient(ctx, "超时退出(" + type + ")");

}

else

{

super.userEventTriggered(ctx, evt);

}

}

@Override

public void channelRead(io.netty.channel.ChannelHandlerContext ctx, Object msg)

{

if (!ctx.channel().isActive()) return;

String sn = GetSN(ctx);

if(!dicSn2Buffer.containsKey(sn)) dicSn2Buffer.put(sn, Unpooled.buffer(1024));

io.netty.buffer.ByteBuf oldBuffer = dicSn2Buffer.get(sn);

if (null != msg)

{

io.netty.buffer.ByteBuf recvBuffer = (ByteBuf) msg;

int size = recvBuffer.readableBytes();

if (size > 0)

{

//recvBuffer.markReaderIndex();

oldBuffer.writeBytes(recvBuffer);

ReferenceCountUtil.release(recvBuffer);

//recvBuffer.resetReaderIndex();

//byte[] recv = new byte[size];

//recvBuffer.readBytes(recv);

//CTxtHelp.AppendLog("接收数据:" + CDataHelper.ArrayByteToString(recv));

}

}

byte head1 = 0; byte head2 = 0; byte head3 = 0; byte head4 = 0; byte head5 = 0; byte head6 = 0;

while (oldBuffer.isReadable())

{

oldBuffer.markReaderIndex();

head1 = oldBuffer.readByte(); if (!oldBuffer.isReadable()) { oldBuffer.resetReaderIndex(); return ; } // 掉包处理

if (HEAD1 == head1)// 垃圾包处理

{

head2 = oldBuffer.readByte(); if (!oldBuffer.isReadable()) { oldBuffer.resetReaderIndex(); return ; }

head3 = oldBuffer.readByte(); if (!oldBuffer.isReadable()) { oldBuffer.resetReaderIndex(); return ; }

head4 = oldBuffer.readByte(); if (!oldBuffer.isReadable()) { oldBuffer.resetReaderIndex(); return ; }

head5 = oldBuffer.readByte(); if (!oldBuffer.isReadable()) { oldBuffer.resetReaderIndex(); return ; }

head6 = oldBuffer.readByte(); if (!oldBuffer.isReadable()) { oldBuffer.resetReaderIndex(); return ; }

if (HEAD2 == head2 && HEAD3 == head3 && HEAD4 == head4 && HEAD5 == head5 && HEAD6 == head6)

{

break;

}

else

{

CTxtHelp.AppendLog("Error,Unable to parse the data2");

}

}

else

{

CTxtHelp.AppendLog("Error,Unable to parse the data1");

}

}

int lengthsize = 4;

if (GetWaitRecvRemain(oldBuffer, lengthsize)) { oldBuffer.resetReaderIndex(); return ; }

byte[] arrlen = new byte[lengthsize]; oldBuffer.readBytes(arrlen);

int lengthdata = CDataHelper.String2Int(CDataHelper.ArrayByteToString(arrlen));// if (-1 == len) return;

if (GetWaitRecvRemain(oldBuffer, lengthdata)) { oldBuffer.resetReaderIndex(); return ; }

byte[] source = new byte[lengthdata]; oldBuffer.readBytes(source);

String data = CDataHelper.ArrayByteToString(source);

CTxtHelp.AppendLog("解析后:" + data);

if (null == data || 0 == data.length() || data.length() - 1 != data.lastIndexOf(SPLIT1)) return;

data = data.substring(1, data.length() - 1);

String[] items = data.split(SPLIT1, -1);

if (null == items || 4 != items.length) return;

String uid = items[0];

String taskid = items[1];

int cmd = CDataHelper.String2Int(items[2]);

String content = items[3];

String back = "";

try

{

switch (cmd)

{

case 1: back = "ok"; break;

case 2: break;

case 3: break;

}

}

catch (Exception ex)

{

CTxtHelp.AppendLog("error@" + ex.getMessage());

}

if (!"".equals(back))

{

byte[] sendBuff = GetProtocol(uid, cmd, back);

ByteBuf out = ctx.alloc().directBuffer(sendBuff.length);

out.writeBytes(sendBuff);

ctx.channel().writeAndFlush(out);

}

if (!oldBuffer.isReadable())

{

oldBuffer.clear();

}

else

{

channelRead(ctx, null);

}

}

boolean GetWaitRecvRemain( io.netty.buffer.ByteBuf buf, int len) {

return buf.readerIndex() + len > buf.writerIndex();

}

String GetSN(io.netty.channel.ChannelHandlerContext ctx)

{

return ctx.channel().remoteAddress().toString().replace("/", "");

}

void RemoveClient(io.netty.channel.ChannelHandlerContext ctx, String errmsg)

{

String sn = GetSN(ctx);

CTxtHelp.AppendLog("客户端退出,errmsg:" + errmsg);

if(dicSn2Buffer.containsKey(sn)) {

io.netty.buffer.ByteBuf byteBuf = dicSn2Buffer.get(sn);

ReferenceCountUtil.release(byteBuf);

dicSn2Buffer.remove(sn);

}

ctx.close();

}

byte[] GetProtocol(String uid, int cmd, String msg)

{

String content = SPLIT1 + uid + SPLIT1 +

System.currentTimeMillis() + SPLIT1 +

CDataHelper.lpad(cmd, 2) + SPLIT1 +

msg + SPLIT1;

StringBuilder data = new StringBuilder();

data.append("HTEMP=");

data.append(CDataHelper.lpad(CDataHelper.GetStringLength(content), 4));

data.append(content);

return CDataHelper.StringToByte(data.toString());

}

String lpad(int number, int length) {

String f = "%0" + length + "d";

return String.format(f, number);

}

}

程序结构:

运行结果:

1. 包解析(正常包+掉包+粘包+垃圾包)

2. 超时清理链路

3. 并发测试

高性能TcpServer(Java) - Netty的更多相关文章

  1. Java Netty简介

    Netty和Mina是Java世界非常知名的通讯框架.它们都出自同一个作者,Mina诞生略早,属于Apache基金会,而Netty开始在Jboss名下,后来出来自立门户netty.io(http:// ...

  2. [转帖]Java Netty简介

    Java Netty简介 https://www.cnblogs.com/ghj1976/p/3779820.html Posted on 2014-06-10 13:41 蝈蝈俊 阅读(2992) ...

  3. java netty socket库和自定义C#socket库利用protobuf进行通信完整实例

    之前的文章讲述了socket通信的一些基本知识,已经本人自定义的C#版本的socket.和java netty 库的二次封装,但是没有真正的发表测试用例. 本文只是为了讲解利用protobuf 进行C ...

  4. 【Jetlang】一个高性能的Java线程库

    actor  Jetlang 提供了一个高性能的Java线程库,该库是 JDK 1.5 中的 java.util.concurrent 包的补充,可用于基于并发消息机制的应用. .net的MS CCR ...

  5. JAVA语言之怎样写出高性能的Java代码?

    本文主要向大家介绍了JAVA语言之怎样写出高性能的 Java 代码?通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助. 在这篇文章中,我们将讨论几个有助于提升Java应用程序性能的方法.我 ...

  6. 项目-高性能TcpServer - 目录

    1.项目-高性能TcpServer - 1.网络通信协议 https://blog.csdn.net/arno1988/article/details/82463225 2.项目-高性能TcpServ ...

  7. 学习 java netty (一) -- java nio

    前言:近期在研究java netty这个网络框架,第一篇先介绍java的nio. java nio在jdk1.4引入,事实上也算比較早的了.主要引入非堵塞io和io多路复用.内部基于reactor模式 ...

  8. 高性能TcpServer(C#) - 1.网络通信协议

    高性能TcpServer(C#) - 1.网络通信协议 高性能TcpServer(C#) - 2.创建高性能Socket服务器SocketAsyncEventArgs的实现(IOCP) 高性能TcpS ...

  9. 高性能TcpServer(C#) - 3.命令通道(处理:掉包,粘包,垃圾包)

    高性能TcpServer(C#) - 1.网络通信协议 高性能TcpServer(C#) - 2.创建高性能Socket服务器SocketAsyncEventArgs的实现(IOCP) 高性能TcpS ...

随机推荐

  1. JWT 使用的另一种声音

    讲真,别再使用JWT了! 把本应该session 中保存的数据 去除敏感字段 保留到客户端   在Web应用中,使用JWT替代session并不是个好主意 适合JWT的使用场景 抱歉,当了回标题党.我 ...

  2. hadoop 源码编译

    hadoop 源码编译 1.准备jar 1) hadoop-2.7.2-src.tar.gz 2) jdk-8u144-linux-x64.tar.gz 3) apach-ant-1.9.9-bin. ...

  3. zz模型剪枝

    论文总结 - 模型剪枝 Model Pruning  发表于 2018-10-03 模型剪枝是常用的模型压缩方法之一.这篇是最近看的模型剪枝相关论文的总结. Deep Compression, Han ...

  4. TVM:

    Hello TVM  发表于 2019-06-29 TVM 是什么?A compiler stack,graph level / operator level optimization,目的是(不同框 ...

  5. java数组的N种打印方式

    int[] array = {1,2,3,4,5}; (1)传统的for循环方式 ;i<array.length;i++) { System.out.println(a[i]); } (2)fo ...

  6. C++面向对象程序设计学习笔记(7)

    模板与异常处理 模板的概念 模板是实现代码重用机制的一种工具,它可以实现类型参数化,即把类型作为参数. 模板分为函数模板和类模板,它们分别允许用户构造模板类和模板函数 函数模板与模板函数 函数模板实际 ...

  7. [LeetCode] 207. Course Schedule 课程清单

    There are a total of n courses you have to take, labeled from 0 to n-1. Some courses may have prereq ...

  8. shell 读取yaml 之 shyaml

    安装shyaml pip3. install shyaml file.yaml文件内容---idc_group: name: bx bx: news_bx: news_bx web3_bx: web3 ...

  9. 结合Spring实现策略模式

    最近系统需要对不同维度的数据进行差异化计算,也就会使用不同算法.为了以后更加容易扩展,结合Spring框架及策略模式对实现架构做了系统设计. 1. 定义策略接口(Strategy): import c ...

  10. netcat 传输T级别大文件

    接收端 nc -d -l 5002 |tar xf - nohup  sh receive.sh  &   发送端 tar cf - . | nc  1.1.1.1  5002 nohup   ...