- 浏览: 63807 次
- 性别:
- 来自: 北京
最新评论
-
创世雨天:
转换后getText就会是乱码 请问有解决办法吗?QQ4027 ...
EditText加入图片混编显示 -
logojimi:
楼主考虑了安装多种桌面,而且没有设置默认桌面的情况?
试试这行 ...
Android程序最小化 -
yuboxin5566:
这个东西可以具体点吗?我可以有你这个东东的全代码么?可以私聊Q ...
EditText加入图片混编显示 -
woaidousha:
那请问个问题,如果是想在listView下面加个expanda ...
ExpandableListView 怎么和其他组件相互整合布局 -
liutao6982:
厉害厉害。这一招都被你想出来啦。很好很强大。支持一下
EditText加入图片混编显示
使用mina传输超过2k以上的数据时(采用tcp方式,如果是UDP方式,好像一次传输的数据不能超过256字节,如果超过mina不会分批次发送,而tcp方式会分批次发送),mina会自动将这些数据分成多次发送。由于是分批次发送数据,所有客服端在接受数据时,需要等所有的数据接受完之后才能解码,否则无法解码,或者只能读取到部分文件。
以下是一个发送、接受大字节数组的主要代码
服务端向客服端发送字节数组
服务端代码:
编码器:
public class ImageDataEncoder extends ProtocolEncoderAdapter {
@Override
public void encode(IoSession session, Object message,
ProtocolEncoderOutput out) throws Exception {
CharsetEncoder charset = Charset.forName("UTF-8").newEncoder();
ImageData image = (ImageData) message;
IoBuffer buffer = IoBuffer.allocate(2048).setAutoExpand(true);
buffer.putString(image.getYh(), charset);// 发送数据类型
buffer.putInt(image.getLength());// 发送字节数组的总长度,共解码时使用
buffer.put(image.getBimage());// 发送字节数据
buffer.flip();
out.write(buffer);
buffer.free();
}
}
ImageData.java
public class ImageData {
private static final long serialVersionUID = 1L;
private String yh = YHConstants.YH_IMG;// 数据类型
public int length = 0;// 字节数组长度
private byte[] bimage;// 待发送的字节数组
private BufferedImage image;//将字节数组转换成图片文件
public ImageData() {
}
public ImageData(byte[] bimage) {
this.bimage = bimage;
}
public byte[] getBimage() {
return bimage;
}
public BufferedImage getImage() {
try {
if (bimage.length > 0) {
ByteArrayInputStream in = new ByteArrayInputStream(bimage);
this.image = ImageIO.read(in);
in.close();
}
} catch (RemoteException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return this.image;
}
public int getLength() {
return bimage.length;
}
public String getYh() {
return yh;
}
public void setBimage(byte[] bimage) {
this.bimage = bimage;
}
public void setYh(String yh) {
this.yh = yh;
}
}
YHConstants.java
public class YHConstants {
public static final int LENGTH = 7;// 命令数据类型
public static final String YH_CMD = "YH CMD ";// 命令数据类型
public static final String YH_IMG = "YH IMG ";// 图片数据类型
}
客服端:
解码器:分段发送的解码器一定要继承CumulativeProtocolDecoder ,这个是专门用来实现这种解码的
package com.seara.socket.codec;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.AttributeKey;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
import com.seara.socket.message.ImageData;
import com.seara.socket.message.YHConstants;
/**
* 接收图片数据,由于图片数据比较大,tcp是采用分段式发送,所有需要等所有数据接收完之后才能解码
*
* 解码原理:首先读取服务器端发送数据的总长度length,然后与当前的buff中的数据长度matchLength比较,如果matchLength>=
* length则认为数据发送完毕, 否則将当前的buff保存起来,在下次发送buff之时合并为一个buff,然后在按照以上条件判断
*
* @author seara
*
*/
public class ImageDataDecoder extends CumulativeProtocolDecoder {
private final AttributeKey CONTEXT = new AttributeKey(this.getClass(),
"context");
@Override
protected boolean doDecode(IoSession session, IoBuffer buff,
ProtocolDecoderOutput out) throws Exception {
CharsetDecoder charset = Charset.forName("UTF-8").newDecoder();
System.out.println("继续解码......." + buff.remaining());
// 取出context
Context ctx = this.getContext(session);// 将contex从session中取出
int length = ctx.getLength();// 数据总长度
IoBuffer buffer = ctx.getBuffer();// 保存数据的buffer
int matchLength = ctx.getMatchLength();// 目前已经发送的数据的总长度
if (0 == length) {// 第一次取值
String yh = buff.getString(YHConstants.LENGTH, charset);
length = buff.getInt();
matchLength = buff.remaining();
ctx.setYh(yh);
ctx.setLength(length);
} else {
matchLength += buff.remaining();
}
ctx.setMatchLength(matchLength);
if (buff.hasRemaining()) {// 如果buff中还有数据
buffer.put(buff);// 添加到保存数据的buffer中
if (matchLength >= length) {// 如果已经发送的数据的长度>=目标数据的长度,则进行解码
byte[] b = new byte[length];
// 一定要添加以下这一段,否则不会有任何数据,因为,在执行buffer.put(buff)时buffer的起始位置已经移动到最后,所有需要将buffer的起始位置移动到最开始
buffer.flip();
buffer.get(b);
ImageData image = new ImageData(b);
out.write(image);
System.out.println("解码完成.......");
return true;
} else {
ctx.setBuffer(buffer);
}
}
return false;// 返回false时,解码器就不会执行解码,返回true是在解码完成
}
/**
* 定义一个内部类,用来封转当前解码器中的一些公共数据,主要是用于大数据解析
*
* @author seara
*
*/
public class Context {
public IoBuffer buffer;
public int length = 0;
public int matchLength = 0;
public String yh = "";
public Context() {
this.buffer = IoBuffer.allocate(1024).setAutoExpand(true);
}
public int getMatchLength() {
return matchLength;
}
public void setMatchLength(int matchLength) {
this.matchLength = matchLength;
}
public IoBuffer getBuffer() {
return buffer;
}
public void setBuffer(IoBuffer buffer) {
this.buffer = buffer;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public String getYh() {
return yh;
}
public void setYh(String yh) {
this.yh = yh;
}
}
public Context getContext(IoSession session) {
Context ctx = (Context) session.getAttribute(CONTEXT);
if (ctx == null) {
ctx = new Context();
session.setAttribute(CONTEXT, ctx);
}
return ctx;
}
}
以下是一个发送、接受大字节数组的主要代码
服务端向客服端发送字节数组
服务端代码:
编码器:
public class ImageDataEncoder extends ProtocolEncoderAdapter {
@Override
public void encode(IoSession session, Object message,
ProtocolEncoderOutput out) throws Exception {
CharsetEncoder charset = Charset.forName("UTF-8").newEncoder();
ImageData image = (ImageData) message;
IoBuffer buffer = IoBuffer.allocate(2048).setAutoExpand(true);
buffer.putString(image.getYh(), charset);// 发送数据类型
buffer.putInt(image.getLength());// 发送字节数组的总长度,共解码时使用
buffer.put(image.getBimage());// 发送字节数据
buffer.flip();
out.write(buffer);
buffer.free();
}
}
ImageData.java
public class ImageData {
private static final long serialVersionUID = 1L;
private String yh = YHConstants.YH_IMG;// 数据类型
public int length = 0;// 字节数组长度
private byte[] bimage;// 待发送的字节数组
private BufferedImage image;//将字节数组转换成图片文件
public ImageData() {
}
public ImageData(byte[] bimage) {
this.bimage = bimage;
}
public byte[] getBimage() {
return bimage;
}
public BufferedImage getImage() {
try {
if (bimage.length > 0) {
ByteArrayInputStream in = new ByteArrayInputStream(bimage);
this.image = ImageIO.read(in);
in.close();
}
} catch (RemoteException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return this.image;
}
public int getLength() {
return bimage.length;
}
public String getYh() {
return yh;
}
public void setBimage(byte[] bimage) {
this.bimage = bimage;
}
public void setYh(String yh) {
this.yh = yh;
}
}
YHConstants.java
public class YHConstants {
public static final int LENGTH = 7;// 命令数据类型
public static final String YH_CMD = "YH CMD ";// 命令数据类型
public static final String YH_IMG = "YH IMG ";// 图片数据类型
}
客服端:
解码器:分段发送的解码器一定要继承CumulativeProtocolDecoder ,这个是专门用来实现这种解码的
package com.seara.socket.codec;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.AttributeKey;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
import com.seara.socket.message.ImageData;
import com.seara.socket.message.YHConstants;
/**
* 接收图片数据,由于图片数据比较大,tcp是采用分段式发送,所有需要等所有数据接收完之后才能解码
*
* 解码原理:首先读取服务器端发送数据的总长度length,然后与当前的buff中的数据长度matchLength比较,如果matchLength>=
* length则认为数据发送完毕, 否則将当前的buff保存起来,在下次发送buff之时合并为一个buff,然后在按照以上条件判断
*
* @author seara
*
*/
public class ImageDataDecoder extends CumulativeProtocolDecoder {
private final AttributeKey CONTEXT = new AttributeKey(this.getClass(),
"context");
@Override
protected boolean doDecode(IoSession session, IoBuffer buff,
ProtocolDecoderOutput out) throws Exception {
CharsetDecoder charset = Charset.forName("UTF-8").newDecoder();
System.out.println("继续解码......." + buff.remaining());
// 取出context
Context ctx = this.getContext(session);// 将contex从session中取出
int length = ctx.getLength();// 数据总长度
IoBuffer buffer = ctx.getBuffer();// 保存数据的buffer
int matchLength = ctx.getMatchLength();// 目前已经发送的数据的总长度
if (0 == length) {// 第一次取值
String yh = buff.getString(YHConstants.LENGTH, charset);
length = buff.getInt();
matchLength = buff.remaining();
ctx.setYh(yh);
ctx.setLength(length);
} else {
matchLength += buff.remaining();
}
ctx.setMatchLength(matchLength);
if (buff.hasRemaining()) {// 如果buff中还有数据
buffer.put(buff);// 添加到保存数据的buffer中
if (matchLength >= length) {// 如果已经发送的数据的长度>=目标数据的长度,则进行解码
byte[] b = new byte[length];
// 一定要添加以下这一段,否则不会有任何数据,因为,在执行buffer.put(buff)时buffer的起始位置已经移动到最后,所有需要将buffer的起始位置移动到最开始
buffer.flip();
buffer.get(b);
ImageData image = new ImageData(b);
out.write(image);
System.out.println("解码完成.......");
return true;
} else {
ctx.setBuffer(buffer);
}
}
return false;// 返回false时,解码器就不会执行解码,返回true是在解码完成
}
/**
* 定义一个内部类,用来封转当前解码器中的一些公共数据,主要是用于大数据解析
*
* @author seara
*
*/
public class Context {
public IoBuffer buffer;
public int length = 0;
public int matchLength = 0;
public String yh = "";
public Context() {
this.buffer = IoBuffer.allocate(1024).setAutoExpand(true);
}
public int getMatchLength() {
return matchLength;
}
public void setMatchLength(int matchLength) {
this.matchLength = matchLength;
}
public IoBuffer getBuffer() {
return buffer;
}
public void setBuffer(IoBuffer buffer) {
this.buffer = buffer;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public String getYh() {
return yh;
}
public void setYh(String yh) {
this.yh = yh;
}
}
public Context getContext(IoSession session) {
Context ctx = (Context) session.getAttribute(CONTEXT);
if (ctx == null) {
ctx = new Context();
session.setAttribute(CONTEXT, ctx);
}
return ctx;
}
}
发表评论
-
Android程序最小化
2011-03-25 14:30 2164/** * 最小化,回到桌面 * */ ... -
Android开发中如何定义和使用数组
2011-03-02 17:12 1553数组在Android开发中是如何定义和使用的呢? 在Andro ... -
EditText加入图片混编显示
2011-02-23 10:32 3981Android的WebView固然强大 ... -
Eclipse中Logcat中文解决办法,重装该ADT即可
2011-02-16 16:57 2528这个问题从一开始接触到Android开发就困扰我很久 ... -
Android 核心分析 之五 -----基本空间划分【转】
2011-01-18 14:23 766基本空间划分 Google给了我们一张系统架构图,在这张图上 ... -
Android核心分析之四 ---手机的软件形态【转】
2011-01-18 14:17 700手机的软件形态 上节我给出了手机的硬件树,本节将 ... -
Android是什么 之三-------手机之硬件形态【转】
2011-01-18 14:16 816Android是什么 之三-------手机之硬件形态 ... -
Android核心分析 之一--------分析方法论探讨之设计意图【转】
2011-01-18 14:09 772分析方法论探讨之设计 ... -
获取string.xml中的可变字符串
2011-01-14 15:47 19761、在string.xml中添加一个字符串,其中含有可变字符% ... -
在代码中获取在AndroidManifest.xml中配置的版本号
2011-01-14 15:42 1632在代码中的获取方法如下: String versionnam ... -
android2.1源码开发过程中的小技巧
2010-12-29 15:07 910归纳总结android2.1源码开发过程中的一些实用的小技巧。 ... -
升级Android SDK到2.3错误的解决办法
2010-12-29 15:01 920升级了2.3的朋友应该知道,升级到2.3后,Eclipse会报 ... -
Android如何解析Intent Filter (转)
2010-12-29 11:22 664匿名性质的运行时绑定使得理解Android如何解析一个隐式 ... -
使用JSON-LIB转换JAVA对象
2010-12-29 11:20 995使用JSON-LIB可以极大的简化JAVA对象转换成 ... -
Android应用程序中Manifest.java文件的介绍(转)
2010-12-29 11:13 1672每一个Android应用程序包含一个manifest文件——A ... -
Android使用外部字体
2010-12-23 11:31 1395有时候,系统自带的字体并不能满足我们特殊的需求,这时候就需要引 ... -
动态获取drawable中的图片
2010-12-22 15:45 12581.首先在drawable中创建一定格式命名的图片。 2.在 ... -
Android配置文件(.properties文件)的使用
2010-12-20 16:39 49691.首先在源代码根目录(src下)下创建一个名为netconf ... -
Android 中离线用户的灰色头像处理方法
2010-12-20 14:04 1036android的图片资源默认是静态的,也就是说是单实例的;如果 ... -
Android Intent Action 大全
2010-12-17 18:59 619String ADD_SHORTCUT_ACTION 动作 ...
相关推荐
mina mina传输对象的示例 mina框架 mina示例
mina自定义编解码 不错的资源 ----其实不怎么样,技术就是拿出来共享的,开源。大家一起前进
mina的使用初步入门mina的使用初步入门mina的使用初步入门
在apache mina传输中可能需要的几个jar包,包括 mina-core-2.0.0-M1.jar slf4j-api-1.5.11.jar slf4j-log4j12-1.5.11.jar log4j-1.2.14.jar
mina的高级使用,mina文件图片传送,
实现了Mina框架简单的换行符编解码的服务器客户端通信,简单自定义协议(报头式)的即时通讯
Mina文件及字符串传输 客户端发送字符串请求。服务端返回客户端请求的文件
最近做rfid读写,C#和java都用udp不用厂家的动态库,udp自己写也简单,但是试了一下Apache mina ,接收的不是string,二十byte[] 数组,简单实现了UDP,网上也有例子,但是不是我要的。可用。
详细介绍mina框架的各个组成部分、服务器端的开发、客户端开发。并根据本人在工程项目中使用的代码,详细讲解了服务器端是客户端实现。实现了json格式的通信、以及文件的上传于下载等功能。图文并茂,以开发者的角度...
使用MINA实现长连接
基于apache mina 的server实现 内存自实现动态数组 基本类型与字节数组转化 基本数据库连接池实现
我自己写的使用mina框架实现cmpp2.0服务端,经过一段使用解决了几个bug现在比较稳定。
Mina文件及字符串传输 客户端发送字符串请求。服务端返回客户端请求的文件
用一个监听既可以传文件又可以传文本 mina 集成spring 传输文件和文本
通讯层使用Mina实现一服务器多客户端的通信,可以修改成一个群体聊天室。Mina是手游开发常用的nio通讯框架,长连接优先使用Mina。希望对你有所帮助!
有丰富的MINA通信软件开发经验,现在已经有成熟的底层框架(结合了反射、DynaBean、Spring等多种技术),可以实现程序自动对上位机和下位机之间的通信协议进行解析,并在国网公司智能电网的大型项目中使用。...
mina连接,mina心跳连接,mina断线重连。其中客户端可直接用在android上。根据各方参考资料,经过自己的理解弄出来的。CSDN的资源分太难得了。
通过mina实现定长报文传输(报文使用ssl加密-mian自带的ssl过滤器)。
最近使用Mina开发一个Java的NIO服务端程序,因此也特意学习了Apache的这个Mina框架。 首先,Mina是个什么东西?看下官方网站(http://mina.apache.org/)对它的解释: Apache的Mina(Multipurpose Infrastructure ...
如何使用mina框架简化android端TCP通信的开发