使用mina当服务器进行纯文本消息或多媒体消息加密会话

首先,对于mina的基本使用这里就不多说了,之前已经转载了一篇很详细的说明。这次想分享的是使用mina框架自定义编解码器,实现发送纯文本和非纯文本消息,带PBE加密。

首先定义要发送的信息包,之前一直想用mina进行图片语音,短视频的传送,把多媒体信息封装成一个类,纯文本文件封装成一个类。然后使用多路分离解码器,虽然这种方法可行,但是发送和接收都直接跳过了handler这层。到最后处理业务逻辑很不方便。

然后尝试值使用一种格式的信息类,消息类型只有是纯文本或非纯文本的标识。一个String类型,真实发送时是发送JSON数据。然后一个byte数组。当是纯文本信息是,标识是‘+‘,byte数组为null,这里不会造成new 一个信息类就会分配多余的内存。当时非纯文本信息时,标识是‘-‘。byte数组存放多媒体信息。

接下来重要的环节就是编写编码器和解码器,思想很简单,根据发送的信息标识进行相应的编码,根据标识进行相应的解码。然后就是加密,这里用到的是PBE对称加密。加密时机是编码器编码时。解密就是在解码器解码时。加密速度我测试了一下。4.1M 加密:191ms 解密:198ms   15M  加密: 600ms    解密:570ms,应该还可以了。

接下来附上代码:

1.信息类

/**

* symbol = ‘+‘ : 纯本文件

* symbol = ‘-‘ : 非纯本文件

* @author Administrator

*/

public class iMoMoMsg {

public char symbol;//判断是否是纯文本文件

public String msgJson;//包含图片详情的解释

public byte[] msgBytes;//图片

}

2.编码类

package com.imomo_codecfactory;

import java.nio.charset.Charset;

import java.nio.charset.CharsetEncoder;

import org.apache.commons.codec.binary.Base64;

import org.apache.mina.core.buffer.IoBuffer;

import org.apache.mina.core.session.IoSession;

import org.apache.mina.filter.codec.ProtocolEncoderAdapter;

import org.apache.mina.filter.codec.ProtocolEncoderOutput;

import com.imomo_msg.iMoMoMsg;

import com.security.PBE;

public class iMoMoEncoder extends ProtocolEncoderAdapter {

CharsetEncoder encoder = Charset.forName("utf-8").newEncoder();

// 纯文本发送格式:头标记(char) + 信息长度(int) +文本信信息(加密byte[])

// 非纯文本发送格式:头标记(char) + 文字信息长度(int) + 文字信息(加密byte[]) + 多媒体信息长度(int) + 多媒体信息(加密byte[])

@Override

public void encode(IoSession session, Object msg, ProtocolEncoderOutput out)

throws Exception {

iMoMoMsg moMsg = (iMoMoMsg) msg;

char symbol = moMsg.symbol;

try {

if (symbol == ‘+‘) {

byte[] msgJsonByte = PBE.enCrypt(moMsg.msgJson.getBytes());//加密

System.out.println("--发送文本信息   = " + moMsg.msgJson);

int msgLen = msgJsonByte.length;

// 2 :最开始的头部symbol,这里是‘-+ ,4表示长度位

IoBuffer io = IoBuffer.allocate(2 + 4 + msgLen).setAutoExpand(

true);

io.putChar(symbol);

io.putInt(msgLen);

io.put(msgJsonByte);

io.flip();

out.write(io);

} else if (symbol == ‘-‘) {

byte[] msgJsonByte = PBE.enCrypt(moMsg.msgJson.getBytes());//加密

byte[] msgBytes = PBE.enCrypt(moMsg.msgBytes);

System.out.println("--发送多媒体信息 = " + moMsg.msgJson

+ " msgBytesLen = " + msgBytes.length);

int textLen = msgJsonByte.length;// 文字信息长度

int msgBytesLen = msgBytes.length;// 图片长度

IoBuffer io = IoBuffer.allocate(

2 + 4 + 4 + textLen + msgBytesLen).setAutoExpand(true);

io.putChar(symbol);

io.putInt(textLen);

io.put(msgJsonByte);

io.putInt(msgBytesLen);

io.put(msgBytes);

io.flip();

out.write(io);

}

} catch (Exception e) {

e.printStackTrace();

}

}

}

3.解码类

package com.imomo_codecfactory;

import java.io.FileOutputStream;

import java.nio.channels.FileChannel;

import java.nio.charset.Charset;

import java.nio.charset.CharsetDecoder;

import java.util.Date;

import org.apache.mina.core.buffer.IoBuffer;

import org.apache.mina.core.session.IoSession;

import org.apache.mina.filter.codec.CumulativeProtocolDecoder;

import org.apache.mina.filter.codec.ProtocolDecoderOutput;

import org.apache.mina.filter.codec.demux.MessageDecoder;

import org.apache.mina.filter.codec.demux.MessageDecoderResult;

import com.imomo_msg.iMoMoMsg;

import com.security.PBE;

public class iMoMoDecoder extends CumulativeProtocolDecoder {

CharsetDecoder decoder = Charset.forName("utf-8").newDecoder();

@Override

protected boolean doDecode(IoSession session, IoBuffer in,

ProtocolDecoderOutput out) throws Exception {

iMoMoMsg moMsg = new iMoMoMsg();

int pos = in.position();

int remaining = in.remaining();

try {

// 判断长度,开头symbol 是char型

if (remaining < 2) {

in.position(pos);

return false;

}

char symbol = in.getChar();// 相当于消费掉字节流

moMsg.symbol = symbol;

if (symbol == ‘+‘) {

int msgJsonLen = 0;// msgJson长度

// 判断是否够解析出的长度

msgJsonLen = in.getInt();

if (remaining - 2 < msgJsonLen || msgJsonLen < 0) {

in.position(pos);

return false;

}

byte[] temp = new byte[msgJsonLen];

in.get(temp);//得到加密后byte数组

moMsg.msgJson = new String(PBE.deCiphering(temp));

out.write(moMsg);

} else if (symbol == ‘-‘) {

// 接收文本信息

int msgJsonLen = 0;// msgJson长度

int msgBytesLen = 0;// msgBytes长度

msgJsonLen = in.getInt();

if (remaining - 2 < msgJsonLen || msgJsonLen < 0) {

in.position(pos);

return false;

}

byte[] temp1 = new byte[msgJsonLen];

in.get(temp1);//得到加密后byte数组

moMsg.msgJson = new String(PBE.deCiphering(temp1));

// 接收图片信息

msgBytesLen = in.getInt();

if (remaining - 2 - 4 - 4 - msgJsonLen < msgBytesLen

|| msgBytesLen < 0) {

in.position(pos);

return false;

}

byte[] temp2 = new byte[msgBytesLen];

in.get(temp2);//得到加密后byte数组

moMsg.msgBytes = PBE.deCiphering(temp2);

out.write(moMsg);

}

} catch (Exception e) {

e.printStackTrace();

in.position(pos);

return false;

}

return true;

}

}

如果对编解码不熟的可以参考mina开发手册。

测试 发送15m的视频:

client handler类里:

@Override

public void sessionOpened(IoSession session) throws Exception {

iMoMoMsg moMoMsg = new iMoMoMsg();

JSONObject textJson = new JSONObject();

textJson.put("type", "login");

textJson.put("id", "201513");

textJson.put("pwd", "1234");

moMoMsg.msgJson = textJson.toJSONString();

moMoMsg.symbol = ‘+‘;

session.write(moMoMsg);

// 发送图片信息

JSONObject multiJson = new JSONObject();

multiJson.put("type", "pic");

multiJson.put("sender", "001");

multiJson.put("getter", "002");

FileInputStream fileInputStream = new FileInputStream("f:\\moshou.avi");

FileChannel channel = fileInputStream.getChannel();

ByteBuffer bytebuffer = ByteBuffer.allocate((int) channel.size());

bytebuffer.clear();

channel.read(bytebuffer);

iMoMoMsg moMoMsg2 = new iMoMoMsg();

moMoMsg2.msgJson = multiJson.toJSONString();

moMoMsg2.msgBytes = bytebuffer.array();

moMoMsg2.symbol = ‘-‘;

session.write(moMoMsg2);

fileInputStream.close();

channel.close();

}

server handler里:

public void messageReceived(IoSession session, Object message)

throws Exception {

super.messageReceived(session, message);

iMoMoMsg moMoMsg = (iMoMoMsg) message;

if(moMoMsg.symbol == ‘+‘){

String msgJson = moMoMsg.msgJson;

System.out.println("服务器 收到纯文本信息 : " + msgJson);

} else if(moMoMsg.symbol == ‘-‘){

String msgJson = moMoMsg.msgJson;

System.out.println("服务器 收到多媒体本信息 : " + msgJson + "多媒体信息长度" + moMoMsg.msgBytes.length);

FileOutputStream fileout = new FileOutputStream("F:\\"

+ new Date().getMinutes() + "-.avi");

FileChannel fc = fileout.getChannel();

fileout.write(moMoMsg.msgBytes);

fc.close();

fileout.close();

}

}

控制台打印:

客户端:

本次加密用时 : 774

本次加密用时 : 651

--发送多媒体信息 = {"getter":"002","sender":"001","type":"pic"} msgBytesLen = 16174624

服务器:

本次解密用时 : 177

本次解密用时 : 597

服务器 收到多媒体本信息 : {"getter":"002","sender":"001","type":"pic"}多媒体信息长度16174616

从上可以看到:加密不管是对文本信息加密还是对多媒体文件加密,都比较耗时间,解密就相对较快。

具体工程:http://download.csdn.net/detail/u011102153/8615791

时间: 2024-08-29 01:12:06

使用mina当服务器进行纯文本消息或多媒体消息加密会话的相关文章

如何用纯文本方式(XML)+HTTP协议调用Workday的web service?

我们知道,Workday系统本身很复杂,其发布的web服务(web service)也很多,而且其中的Web 服务(web service)中定义的Schema也很复杂.如果用AXIS或者XFire生成存根代码调用其相应模块的web service,比如Human Resource模块,也可以,但是生成的存根代码比较复杂,而且Workday的web服务本身也在不断的升级过程中,在升级的过程中,其Schema的信息也在不断变化和调整过程中,那么有没有一种以不变应万变的方式,答案是肯定的.那就是通过

EQueue - 一个纯C#写的分布式消息队列介绍2

一年前,当我第一次开发完EQueue后,写过一篇文章介绍了其整体架构,做这个框架的背景,以及架构中的所有基本概念.通过那篇文章,大家可以对EQueue有一个基本的了解.经过了1年多的完善,EQueue无论是功能上还是成熟性上都完善了不少.所以,希望再写一篇文章,介绍一下EQueue的整体架构和关键特性. EQueue架构 EQueue是一个分布式的.轻量级.高性能.具有一定可靠性,纯C#编写的消息队列,支持消费者集群消费模式. 主要包括三个部分:producer, broker, consume

利用htmlparser提取网页纯文本的例子

import org.htmlparser.Node; import org.htmlparser.NodeFilter; import org.htmlparser.Parser; importorg.htmlparser.filters.TagNameFilter; import org.htmlparser.tags.TableTag; import org.htmlparser.util.NodeList; /** * 标题:利用htmlparser提取网页纯文本的例子 */ publi

数据抽取工具——DMCTextFilter V4.2(纯文本抽出通用程序库)

DMCTextFilter V4.2是由北京红樱枫软件有限公司研制和开发的纯文本抽出通用程序库产品.本产品可以从各种各样的文档格式的数据中或从插入的OLE对象中,完全除掉特殊控制信息,快速抽出纯文本数据信息.便于用户实现对多种文档数据资源信息进行统一管理,编辑,检索和浏览.本产品采用了先进的多语言.多平台.多线程的设计理念,支持多国语言(英语,中文简体,中文繁体,日本语,韩国语),多种操作系统(Windows,Solaris,Linux,IBM AIX,Macintosh,HP-UNIX),多种

数据抽取——纯文本抽出程序库DMCTextFilter

数据抽取工具 纯文本抽出程序库DMCTextFilter DMCTextFilter V4.2是由北京红樱枫软件有限公司研制和开发的纯文本抽出通用程序库产品.本产品可以从各种各样的文档格式的数据中或从插入的OLE对象中,完全除掉特殊控制信息,快速抽出纯文本数据信息.便于用户实现对多种文档数据资源信息进行统一管理,编辑,检索和浏览. 一.应用案例 在实际的推广和应用中,红樱枫的通用文本抽出程序软件被应用到了多个领域,如:信息资源开发利用,智能搜索引擎,情报分析和服务,信息安全,企业知识门户,数字图

C#-MVC开发微信应用(3)--文本消息和图文消息的应答

最近咨询微信的人很多,感觉这块也是一块商机,也为了演示SNF快速开发平台的优势,就用SNF快速开发平台开发出一套微信应用程序.使用<SNF.CodeGenerator>代码生成工具可以节省大量时间. 在前面两篇两篇随笔<C#-MVC开发微信应用(1)--开始使用微信接口>和<C#-MVC开发微信应用(2)--开始使用微信接口>里面,大致介绍了我微信应用的框架构建,本随笔继续介绍这一主题,介绍消息应答里面的文本应答和图文应答的过程. 我们知道,给手机用户发送响应消息,它可

描文本和纯文本做推广优化SEO缔造利润的钱景

情节此次的优化经验,分享我对关于三种外链形式的优错误谬误观点: 第一种是超文本链接,这种url能够直接点击入站点,这么的uri假如文章的内容斗劲吸援用户,内容里插入超文本链接,用户在看了这么的内容后,想看见更出色的内容便会点击這个超链接,这么的url不单能提高这个上网站的权重,对流量的提高也很可不美观. 虽说这种链接对优化的补益最好,不外它在SEO优化中发布是很罕有的,所以列位站长伴侣能用的这种超文本链接更好. 第三,纯文本链接.锚文本链接对优化的效用众多站长都很理解了.也是浑如说郁闷的.通俗上

数据格式转换(二)纯文本抽出

DMCTextFilter是由北京红樱枫软件有限公司研制和开发的纯文本抽出通用程序库产品.本产品可以从各种各样的文档格式的数据中或从插入的OLE对象中,完全除掉特殊控制信息,快速抽出纯文本数据信息.便于用户实现对多种文档数据资源信息进行统一管理,编辑,检索和浏览. 本产品采用了先进的多语言.多平台.多线程的设计理念,支持多国语言(英语,中文简体,中文繁体,日本语,韩国语),多种操作系统(Windows,Solaris,Linux,IBM AIX,Macintosh,HP-UNIX),多种文字集合

jQuery截取字符串、日期字符串转Date、获取html中的纯文本

jQuery截取字符串.日期字符串转Date.获取html中的纯文本. var com = com || {}; (function ($, com) { /* * 截取字符串 * @param str:要截取的字符串 * @param len:保留多少字符 * @param symbol:超过之后字符串末端要添加的字符 */ com.cutStr = function (str, len, symbol) { if (symbol == undefined) { symbol = "...&q