maven项目
https://github.com/solq360/common

  • 链式编/解码
  • 链路层链式处理
  • 管道管理socket
  • 多协议处理非常方便
  • 仿netty NioEventLoop 单线程串行处理

========
侍加功能 :

  • 自动化编/解码
  • rpc 接口增强使用

简单聊天例子

server

TestNioServer

//创建session管理工厂
ISessionFactory sessionFactory = new SessionFactory();
//创建编/解码管理
ICoderParserManager coderParserManager = new CoderParserManager();
//注册包编/解码,处理业务
coderParserManager.register(CoderParser.valueOf("server chat", PackageDefaultCoder.valueOf(), new ChatTestServerHandle()));
//创建ServerSocket 实例
ServerSocket serverSocket=ServerSocket.valueOf(SocketChannelConfig.valueOf(6969), 10,20,coderParserManager, sessionFactory); //启动服务
serverSocket.start();
//阻塞当前线程
serverSocket.sync();
//关闭处理
serverSocket.stop();

client

TestNioClient
传统方式连接

	//创建编/解码管理
ICoderParserManager coderParserManager = new CoderParserManager();
//注册包编/解码,处理业务
coderParserManager.register(CoderParser.valueOf("chat", PackageDefaultCoder.valueOf(), new ChatHandle()));
//创建ClientSocket 实例
final ClientSocket clientSocket = ClientSocket.valueOf(SocketChannelConfig.valueOf(6969), new SocketPool("client", null), coderParserManager, new EmptyHandle()); //模拟连接之后发送消息
Timer timer = new Timer();
timer.schedule(new TimerTask() { @Override
public void run() {
clientSocket.send("连接服务器成功");
System.out.println("send ");
this.cancel();
}
}, 1000); //启动服务
clientSocket.start();
//阻塞当前线程
clientSocket.sync();
//关闭处理
clientSocket.stop();

服务器方式连接

	//创建session管理工厂
ISessionFactory sessionFactory = new SessionFactory();
//创建编/解码管理
ICoderParserManager coderParserManager = new CoderParserManager();
//注册包编/解码,处理业务
coderParserManager.register(CoderParser.valueOf("chat", PackageDefaultCoder.valueOf(), new ChatHandle()));
//创建ClientSocket 实例
final ServerSocket serverSocket = ServerSocket.valueOf(SocketChannelConfig.valueOf(8888), 10, 20, coderParserManager, sessionFactory); //模拟连接之后发送消息
Timer timer = new Timer();
timer.schedule(new TimerTask() { @Override
public void run() {
System.out.println("registerClientSocket");
//主动连接服务器
ClientSocket clientSocket = serverSocket.registerClient(SocketChannelConfig.valueOf(6969));
clientSocket.send("连接服务器成功");
this.cancel();
}
}, 1000); //启动服务
serverSocket.start();
//阻塞当前线程
serverSocket.sync();
//关闭处理
serverSocket.stop();

源码实现过程

链式编/解码

  • 由 多个 ICoder 输入/输出转换处理
  • CoderParser 类组装多个 ICoder
  • 编/码处理器 注意优先级
  • nio read -> packageCoder -> link coders -> handle
  • handle write -> link coders -> packageCoder -> nio write
  • 由 ICoderParserManager 管理调用处理
public interface ICoderParserManager {

    /**
* 解码处理
*
* @return CoderResult
* */
CoderResult decode(ByteBuffer buffer, ICoderCtx ctx); /**
* 编码处理
* */
ByteBuffer encode(Object message, ICoderCtx ctx); void error(ByteBuffer buffer, ICoderCtx ctx); /** 注册 编/码处理器 */
void register(CoderParser coderParser);
}

其中核心
decode
encode

  @Override
public CoderResult decode(ByteBuffer buffer, ICoderCtx ctx) {
final SocketChannelCtx socketChannelCtx = (SocketChannelCtx) ctx;
final ClientSocket clientSocket = socketChannelCtx.getClientSocket(); for (CoderParser coderParser : coderParsers.values()) {
final IPackageCoder packageCoder = coderParser.getPackageCoder();
final ICoder<?, ?>[] linkCoders = coderParser.getCoders();
final IHandle handle = coderParser.getHandle();
Object value = null;
synchronized (buffer) {
// 已解析完
if (socketChannelCtx.getCurrPackageIndex() >= buffer.limit()) {
return CoderResult.valueOf(ResultValue.UNFINISHED);
}
// 包协议处理
if (!packageCoder.verify(buffer, ctx)) {
continue;
}
// 包解析
value = packageCoder.decode(buffer, ctx);
if (value == null) {
// 包未读完整
return CoderResult.valueOf(ResultValue.UNFINISHED);
}
}
// 链式处理
if (linkCoders != null) {
for (ICoder coder : linkCoders) {
value = coder.decode(value, ctx);
if (value == null) {
throw new CoderException("解码出错 : " + coder.getClass());
}
}
}
// 业务解码处理
value = handle.decode(value, ctx);
clientSocket.readBefore(socketChannelCtx, value);
handle.handle(value, ctx);
clientSocket.readAfter(socketChannelCtx, value); return CoderResult.valueOf(ResultValue.SUCCEED);
}
return CoderResult.valueOf(ResultValue.NOT_FIND_CODER);
} @Override
public ByteBuffer encode(Object message, ICoderCtx ctx) { for (CoderParser coderParser : coderParsers.values()) {
final IPackageCoder packageCoder = coderParser.getPackageCoder();
final ICoder<?, ?>[] linkCoders = coderParser.getCoders();
final IHandle handle = coderParser.getHandle();
// 业务检查
if (!handle.verify(message, ctx)) {
continue;
}
// 业务编码处理
Object value = handle.encode(message, ctx);
// 链式处理
if (linkCoders != null) {
for (int i = linkCoders.length - 1; i >= 0; i--) {
ICoder coder = linkCoders[i];
value = coder.encode(value, ctx);
if (value == null) {
throw new CoderException("编码出错 : " + coder.getClass());
}
}
}
// 打包消息处理
value = packageCoder.encode(value, ctx);
if (value != null) {
return (ByteBuffer) value;
}
throw new CoderException("编码出错 :" + packageCoder.getClass());
} throw new CoderException("未找到编/解码处理器 ");
}
  • 半包/帖包处理 : AbstractISocketChannel doRead方法摘要,根据解码返回的状态做处理。
  • 半包:当不是完成状态时,继续解码,从最后一次包索引开始处理
  • 帖包:当完成包解码移动包索引,等侍下轮解码处理

       boolean run = true;
    // 粘包处理
    while (run) {
    ByteBuffer cpbuffer = socketChannelCtx.coderBegin();
    cpbuffer.mark();
    CoderResult coderResult = coderParserManager.decode(cpbuffer, socketChannelCtx);
    switch (coderResult.getValue()) {
    case SUCCEED:
    break;
    case NOT_FIND_CODER:
    final int readySize = socketChannelCtx.getWriteIndex() - socketChannelCtx.getCurrPackageIndex();
    final int headLimit = 255;
    if (readySize >= headLimit) {
    throw new CoderException("未找到编/解码处理器 ");
    }
    run = false;
    break;
    case UNFINISHED:
    case UNKNOWN:
    case ERROR:
    default:
    run = false;
    // TODO throw
    break;
    }
    }

http://www.cnblogs.com/solq/p/4585496.html

java nio 网络框架实现(转)的更多相关文章

  1. java nio 网络框架

    https://github.com/solq360/common 主要运行在android 平台 解决自动化编/解码,等等.. 模块 解决问题/实现处理 备注 负责人 进度 录音播放 AudioRe ...

  2. java nio 网络框架实现

    maven项目 https://github.com/solq360/common 链式编/解码 链路层链式处理 管道管理socket 多协议处理非常方便 仿netty NioEventLoop 单线 ...

  3. Netty | 第1章 Java NIO 网络编程《Netty In Action》

    目录 前言 1. Java 网络编程 1.1 Javs NIO 基本介绍 1.2 缓冲区 Buffer 1.2 通道 Channel 1.3 选择器 Selector 1.4 NIO 非阻塞网络编程原 ...

  4. Java NIO通信框架在电信领域的实践

    [http://www.codeceo.com/article/java-nio-communication.html]   华为电信软件技术架构演进 Java NIO框架在技术变迁中起到的关键作用 ...

  5. Java NIO 网络编程基础

    Java NIO提供了一套网络api,可以用来处理连接数很多的情况.他的基本思想就是用一个线程来处理多个channel. 123456789101112131415161718192021222324 ...

  6. JAVA NIO异步通信框架MINA选型和使用的几个细节(概述入门,UDP, 心跳)

    Apache MINA 2 是一个开发高性能和高可伸缩性网络应用程序的网络应用框架.它提供了一个抽象的事件驱动的异步 API,可以使用 TCP/IP.UDP/IP.串口和虚拟机内部的管道等传输方式.A ...

  7. Java NIO网络编程demo

    使用Java NIO进行网络编程,看下服务端的例子 import java.io.IOException; import java.net.InetAddress; import java.net.I ...

  8. 基于NIO的Netty网络框架

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

  9. BIO & NIO & NIO常见框架

    BIO & NIO BIO - Blocking IO - 同步式阻塞式IO --- UDP/TCP NIO - New  IO - 同步式非阻塞式IO AIO  - Asynchronous ...

随机推荐

  1. 【从翻译mos文章】SGA_TARGET与SHMMAX关系

    SGA_TARGET与SHMMAX关系 参考原始: Relationship Between SGA_TARGET and SHMMAX (文件 ID 1527109.1) 申请: Oracle Da ...

  2. WPF案例 (四) 模拟Windows7桌面任务栏

    原文:WPF案例 (四) 模拟Windows7桌面任务栏 这个程序模彷了Windows7的桌面任务栏,当在桌面上双击某个快捷方式时,将打开一个新的子界面,并且在任务栏里创建一个链接到此界面的任务栏图标 ...

  3. MooTools,jQuery库的一些比对

    jQuery与MooTools库的一些比对   今天就我自己的一些认识比对下这两个JS框架,更多的是希望大家能够对MooTools这个JS框架有更多的认识.毕竟,大多数从事web前端的人对上手容易的j ...

  4. 大话设计模式C++达到-文章12章-外观模式

    一.UML画画 关键词:添加Facade层. 二.概念 外观模式:为子系统中的一组接口提供一个一致的界面.此模式定义了一个高层接口,这个接口使得这一子系统更加easy使用. 三.说明 Q:外观模式在什 ...

  5. Sqlite 扩展功能 GET_PHONEBOOK_INDEX

    在联系人数据库设计中遇到了这个函数,晚上找了半天没找到答案. GET_PHONEBOOK_INDEX This function will produce a normalized upper cas ...

  6. 深入浅出KnockoutJS

    深入浅出KnockoutJS 写在前面,本文资料大多来源网上,属于自己的学习笔记整理. 其中主要内容来自learn.knockoutjs.com,源码解析部分资料来自司徒正美博文<knockou ...

  7. Windows Phone开发(2):竖立自信,初试锋茫

    原文:Windows Phone开发(2):竖立自信,初试锋茫 上一篇文章中,我们聊了一些"大炮"话题,从这篇文章开始,我们一起来学习WP开发吧. 一.我们有哪些装备. 安装完VS ...

  8. SQL注入问题

    斌斌 (给我写信) 原创博文(http://blog.csdn.net/binbinxyz),转载请注明出处! 背景:对于ibaits参数引用可以使用#和$两种写法,其中#写法会采用预编译方式,将转义 ...

  9. Red Gate系列之六 SQL Test 1.0.12.3 Edition SQL测试工具 完全破解+使用教程

    原文:Red Gate系列之六 SQL Test 1.0.12.3 Edition SQL测试工具 完全破解+使用教程 Red Gate系列之六 SQL Test 1.0.12.3 Edition S ...

  10. 【原创】leetCodeOj --- Candy 解题报告

    题目地址: https://leetcode.com/problems/candy/ 题目内容: Candy Total Accepted: 43150 Total Submissions: 2038 ...