源码下载 -> 提取码  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. 201871010133 赵永军《面向对象程序设计(java)》第六、七周学习总结

    201871010133 赵永军<面向对象程序设计(java)>第六.七周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ ...

  2. HardFault_Handler的方法转载

    在硬汉平台看到一个比较好的帖子,关于如何定位HardFault_Handler,这里要记录下网址. http://www.armbbs.cn/forum.php?mod=viewthread& ...

  3. JDOJ 2225 工资计划

    JDOJ 2225: 工资计划 https://neooj.com/oldoj/problem.php?id=2225 Description 高考结束后,同学们大都找到了一份临时工作,渴望挣得一些零 ...

  4. Codechef Chef Cuts Tree

    该思博的时候就思博到底,套路的时候不能再套路的一道题 首先我们将联通块的大小平方和进行转化,发现它就等价于连通点对数,而这个可以转化为连接两点的边数(距离)和 所以我们考虑第\(i\)天时,一个点对\ ...

  5. Linux性能优化实战学习笔记:第十二讲

    一.性能优化方法论 不可中断进程案例 二.怎么评估性能优化的效果? 1.评估思路 2.几个为什么 1.为什么要选择不同维度的指标? 应用程序和系统资源是相辅相成的关系 2.性能优化的最终目的和结果? ...

  6. [LeetCode] 718. Maximum Length of Repeated Subarray 最长的重复子数组

    Given two integer arrays A and B, return the maximum length of an subarray that appears in both arra ...

  7. python实现的WebSocket客户端

    code #coding=utf- import json import time from websocket import create_connection ws = create_connec ...

  8. GreenPlum 大数据平台--segment 失效问题恢复

    1,问题检查 [gpadmin@greenplum01 conf]$ psql -c "select * from gp_segment_configuration where status ...

  9. ApartmentState.STA

    需要设置子线程 ApartmentState 为 STA 模式,但 Task 又不能直接设置 ApartmentState,因此需要用 Thread 来封装一下. using System.Threa ...

  10. pyqt助手中安装Qt帮助文档

    一.个人安装环境 1.Windows7x64_SP1 2.anaconda2.5.0 + python2.7(anaconda集成,不需单独安装) 3.pyinstaller3.0 4.通过Anaco ...