- 浏览: 66423 次
- 性别:
- 来自: 北京
最新评论
-
创世雨天:
转换后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 2280/** * 最小化,回到桌面 * */ ... -
Android开发中如何定义和使用数组
2011-03-02 17:12 1667数组在Android开发中是如何定义和使用的呢? 在Andro ... -
EditText加入图片混编显示
2011-02-23 10:32 4060Android的WebView固然强大 ... -
Eclipse中Logcat中文解决办法,重装该ADT即可
2011-02-16 16:57 2572这个问题从一开始接触到Android开发就困扰我很久 ... -
Android 核心分析 之五 -----基本空间划分【转】
2011-01-18 14:23 803基本空间划分 Google给了我们一张系统架构图,在这张图上 ... -
Android核心分析之四 ---手机的软件形态【转】
2011-01-18 14:17 767手机的软件形态 上节我给出了手机的硬件树,本节将 ... -
Android是什么 之三-------手机之硬件形态【转】
2011-01-18 14:16 904Android是什么 之三-------手机之硬件形态 ... -
Android核心分析 之一--------分析方法论探讨之设计意图【转】
2011-01-18 14:09 812分析方法论探讨之设计 ... -
获取string.xml中的可变字符串
2011-01-14 15:47 20141、在string.xml中添加一个字符串,其中含有可变字符% ... -
在代码中获取在AndroidManifest.xml中配置的版本号
2011-01-14 15:42 1743在代码中的获取方法如下: String versionnam ... -
android2.1源码开发过程中的小技巧
2010-12-29 15:07 958归纳总结android2.1源码开发过程中的一些实用的小技巧。 ... -
升级Android SDK到2.3错误的解决办法
2010-12-29 15:01 972升级了2.3的朋友应该知道,升级到2.3后,Eclipse会报 ... -
Android如何解析Intent Filter (转)
2010-12-29 11:22 706匿名性质的运行时绑定使得理解Android如何解析一个隐式 ... -
使用JSON-LIB转换JAVA对象
2010-12-29 11:20 1029使用JSON-LIB可以极大的简化JAVA对象转换成 ... -
Android应用程序中Manifest.java文件的介绍(转)
2010-12-29 11:13 1705每一个Android应用程序包含一个manifest文件——A ... -
Android使用外部字体
2010-12-23 11:31 1438有时候,系统自带的字体并不能满足我们特殊的需求,这时候就需要引 ... -
动态获取drawable中的图片
2010-12-22 15:45 13031.首先在drawable中创建一定格式命名的图片。 2.在 ... -
Android配置文件(.properties文件)的使用
2010-12-20 16:39 50031.首先在源代码根目录(src下)下创建一个名为netconf ... -
Android 中离线用户的灰色头像处理方法
2010-12-20 14:04 1104android的图片资源默认是静态的,也就是说是单实例的;如果 ... -
Android Intent Action 大全
2010-12-17 18:59 659String ADD_SHORTCUT_ACTION 动作 ...
相关推荐
在标题和描述中提到的“mina传输对象的示例”指的是如何在Mina框架下处理和传输自定义的数据对象。Mina允许开发者通过事件驱动和异步I/O模型来高效地构建网络服务。 Mina的核心组件包括: 1. **Session**: 表示...
总结起来,基于Apache Mina的Server实现涉及到的核心技术包括:利用Mina框架进行网络通信、内存自实现动态数组以优化内存管理、基本类型与字节数组的转化以适应网络数据传输,以及使用数据库连接池提高数据库访问...
6. **返回编码结果**:最后,将编码后的字节数组返回给MINA框架,它会负责将这些字节发送到网络。 7. **配置MINA**:在你的MINA服务端或客户端配置中,注册你的自定义编码器,这样MINA在处理数据时会自动调用你的...
在"mina学习基础-入门实例-传输定长报文(三)"这个主题中,我们将深入探讨如何使用Mina实现定长报文的传输,并且利用Mina内置的SSL过滤器进行报文加密。 首先,让我们了解什么是定长报文。在通信协议中,定长报文是...
在创建自定义协议的DEMO中,开发者可能首先会定义一个ProtocolEncoder接口的实现,用来将应用层对象转换成ByteBuf(MINA中的字节数组表示)。接着,会实现ProtocolDecoder接口,负责将接收到的ByteBuf反序列化为应用...
客户端会将图片数据转化为字节数组,然后通过MINA的`ByteBuffer`发送给服务器。 ```java public class MinaClient { private static final String SERVER_ADDRESS = "localhost"; private static final int PORT ...
解码器将接收到的原始字节数组转换为应用级别的对象,而编码器则反之。接下来,注册一个UDPDatagramHandler,它会在接收到数据包时被调用。 在MINA的过滤器链中,你可以添加自定义的过滤器来实现特定的功能,比如...
4. 在MINA服务端和客户端中使用生成的Java类:将数据序列化为字节数组,通过MINA的ByteBuffer进行传输;在接收端反序列化恢复数据。 5. 集成MINA事件处理器:在MINA的IoHandler或Filter中处理接收到的数据,进行反...
在这个场景中,"mina解码器"是指使用MINA框架来实现自定义的编码和解码逻辑,以处理网络数据的收发。 解码器(Decoder)和编码器(Encoder)是MINA框架中用于处理数据传输的核心组件。它们分别负责将接收到的原始...
1. **编码器(Encoder)**: 编码器负责将Java对象转化为字节数组。例如,对于文件上传,我们可以创建一个自定义的`FileEncoder`,它将文件内容转化为适合网络传输的格式,可能包括分割大文件成多个小块、添加头部...
// 将字节数组转换为业务对象 MyBusinessObject obj = deserialize(data); return obj; } // 序列化/反序列化方法... } ``` 最后,我们需要在处理器中注册这个自定义解码器。这通常在`MinaHandler`类中完成,...
5. **序列化与反序列化**:在IoHandler中,我们需要将对象转换为字节数组进行发送,接收到字节流后反序列化回对象。 6. **绑定与连接**:服务端绑定到指定端口,客户端连接到服务端的IP和端口。 7. **数据交换**:...
- **Buffer类**:MINA中的Buffer类提供了一种高效的方式来读写网络数据,它支持直接操作字节数组,避免了不必要的数据拷贝。 - **IoSession接口**:代表网络连接的会话,包含了连接状态、传输统计信息以及与特定...
例如,我们可以编写一个方法将十进制数转换为二进制,或者将十六进制字符串解析为字节数组,以便于数据的编码和解码。 总的来说,通过SpringBoot集成Mina框架,我们可以构建一个高性能的Socket服务器,处理客户端的...
3. **编码/解码流程**:编码器会将业务对象转化为字节数组,解码器则负责将接收到的字节数组还原为业务对象。 4. **错误处理**:在网络通信中,数据可能会丢失或损坏,因此编解码器需要有容错机制,如错误检测和重...
本指南主要介绍了MINA 2.0的基本使用方法,包括NIO的介绍、MINA框架的核心组件以及与传统BIO(Blocking I/O)模式的对比。 NIO(New I/O),顾名思义,是Java提供的一个新I/O标准,它从Java 1.4版本开始引入,主要...
Spring Integration的Mina模块提供了一系列的转换器,如`ByteArrayStringDecoder`和`StringEncoder`,它们可以方便地将字节数组转换为字符串,或者反之。 在实际应用中,我们可能会遇到并发和性能问题。Spring和...
- **序列化**:将 Java 对象转换成字节数组,以便在网络上传输。 - **传输**:通过特定的传输协议将数据包发送到目标节点。 - **交换**:实现请求与响应之间的交互过程。 - **RPC 模型**:定义了服务的发布、...
文章接着对阻塞I/O技术进行了详尽的分析,并在此基础上研究和学习了JDK1.4中提出的NIO技术,指出NIO技术相较于传统的流I/O技术,主要有两大改进点:一是提供了面向块的、非阻塞的I/O处理能力;二是让Java应用程序...