`
huaye2007
  • 浏览: 38576 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

socket 与 mina 交互数据

 
阅读更多

之前网上查了些资料,有些blog说mina做服务端,socket做客户端,没法用DemuxingProtocolCodecFactory,只能用TextLineCodecFactory协议解析,但要是传文件,这个东东根本就没用,事实上,服务器很大可能是要传文件的,mina做服务端,客户端可能是不同的。比如用mina的客户端写,用nio自己写,用socket自己写,用C语言自己写。

本次测试例子:使用socket传送较长字符串,如果传送文件,也是一样的过程,先将字符串或者文件转换成byte数组

其实如果理解mina的协议解析的话就会非常简单处理这些解码:

大体思想:协议一般有头信息 告诉程序需要读取多少字节,程序就可以不断读取了,知道在哪个字节时候就不用再往后读了。

IoBuffer读取的时候就像一个管道,读取了这部分数据,这部分数据就没有,其实IO流就是这样

Socket客户端:

package com.test;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.charset.Charset;

import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketConnector;


public class client {
	

	
	public static void main(String[] args) throws Exception{
		Socket socket = new Socket("127.0.0.1",9123);
		OutputStream os = socket.getOutputStream();
		String str = "";
		for(int i=0;i<100;i++){
			str = str + "我们都是中国人啊!";
		}
		byte[] bytes = str.getBytes("utf-8");
		System.out.println("数据byte长度:"+bytes.length);
		os.write(i2b(bytes.length));
		os.write(bytes);
		os.flush();

		InputStream is = null;
		
		is = socket.getInputStream();
		byte[] intByte = new byte[4];
		is.read(intByte);
		int msgLength = b2i(intByte);
		System.out.println("int:"+msgLength);
		int readPosition = 0;
		byte[] byteArray = new byte[msgLength];
		while(readPosition < msgLength){
			int value = is.read(byteArray, readPosition, msgLength-readPosition);
			if(value == -1){
				break;
			}
			readPosition += value;
			
		}
		System.out.println(new String(byteArray,"utf-8"));
		System.out.println("byteArray Length:"+byteArray.length+" string Length:"+new String(byteArray,"utf-8").length());
		if(os != null){
			os.close();
		}
		if(is != null){
			is.close();
		}
	}
	
	// 网上抄来的,将 int 转成字节
	public static byte[] i2b(int i) {
	return new byte[] { (byte) ((i >> 24) & 0xFF),
	(byte) ((i >> 16) & 0xFF), (byte) ((i >> 8) & 0xFF),
	(byte) (i & 0xFF) };
	}
	
	public static int b2i(byte[] b) {
		int value = 0;
		for (int i = 0; i < 4; i++) {
		int shift = (4 - 1 - i) * 8;
		value += (b[i] & 0x000000FF) << shift;
		}
		return value;
	}

}
socket先发送测试数据,然后接收服务端返回的数据

package com.test;

import java.io.File;
import java.io.FileOutputStream;
import java.nio.charset.Charset;

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 org.apache.mina.filter.codec.demux.MessageDecoder;
import org.apache.mina.filter.codec.demux.MessageDecoderResult;



public class BaseMessageDecoder  implements MessageDecoder {
	AttributeKey CONTEXT = new AttributeKey(getClass(),"context");
	/**
	 * 是否适合解码
	 * */
	public MessageDecoderResult decodable(IoSession session, IoBuffer in) {
		
		// TODO Auto-generated method stub
	
		return MessageDecoderResult.OK;
	}

	/**
	 * 数据解码
	 * */
	public MessageDecoderResult decode(IoSession session, IoBuffer in,
			ProtocolDecoderOutput outPut) throws Exception {
		// TODO Auto-generated method stub
		Context context = (Context) session.getAttribute(CONTEXT);
		// TODO Auto-generated method stub
			IoBuffer buffer = in;
			if(context == null || !context.init){
				IoBuffer b = buffer.get(new byte[4]);
				byte[] intByte = b.array();
				int num = b2i(intByte);
				System.out.println("长度:"+num);
				context = new Context();
				context.number = num;
				context.position = 0;
				context.byteArray = new byte[num];
				context.init = true;
				while(buffer.hasRemaining()){
					byte c = buffer.get();
					context.byteArray[context.position] = c;
					context.position++;
				}
			}else{
				while(buffer.hasRemaining()){
					byte c = buffer.get();
					context.byteArray[context.position] = c;
					if( context.position == context.number-1){
						System.out.println(new String(context.byteArray,"utf-8"));
						IoBuffer buff = IoBuffer.allocate(1024).setAutoExpand(true);
						buff.put(i2b(context.number));
						buff.put(context.byteArray);
						buff.flip();
						outPut.write(buff);
						return MessageDecoderResult.OK;
					}
					context.position++;
				}
			}
			session.setAttribute(CONTEXT,context);
			return MessageDecoderResult.NEED_DATA;
	}

	/**
	 * 解码完成
	 * */
	public void finishDecode(IoSession session, ProtocolDecoderOutput outPut)
			throws Exception {
		// TODO Auto-generated method stub
	}
	public static int b2i(byte[] b) {
		int value = 0;
		for (int i = 0; i < 4; i++) {
		int shift = (4 - 1 - i) * 8;
		value += (b[i] & 0x000000FF) << shift;
		}
		return value;
		}
	public static byte[] i2b(int i) {
		return new byte[] { (byte) ((i >> 24) & 0xFF),
		(byte) ((i >> 16) & 0xFF), (byte) ((i >> 8) & 0xFF),
		(byte) (i & 0xFF) };
		}
	class Context {
		public  Integer number;
		public byte[] byteArray;
		public Integer position;
		public boolean init;
	}
}
因传送字符串较长,执行多次调用decode方法,需要中间变量记住之前的部分字段值。

IoBuffer buff = IoBuffer.allocate(1024).setAutoExpand(true);
buff.put(i2b(context.number));
buff.put(context.byteArray);
buff.flip();
outPut.write(buff);

这段代码本应该写在BaseMessageEncoder的encode方法中,但出于我并没有在服务端需要这些字符串值,所以直接将数据方法IoBuffer,服务端直接写回客户端

测试数据OK。

源代码


分享到:
评论
1 楼 mixaceh 2014-07-04  

相关推荐

    Socket及Mina的讲解

    Apache Mina是一个轻量级、高性能的网络通信框架,它简化了网络编程,提供了与多种协议(如TCP、UDP、HTTP、FTP等)交互的能力。Mina的核心设计是基于事件驱动和异步I/O模型,这使得它在处理大量并发连接时表现出色...

    socket通信,mina长连接通信

    Socket通信和MINA长连接是网络编程中的两个关键概念,主要应用于服务器与客户端之间的数据交互。在移动应用开发,特别是需要实时推送功能时,这两种技术显得尤为重要。 **Socket通信** Socket,也称为套接字,是...

    Android-MinaSocket一款基于Mina的Socket长连接库

    总结起来,`Android-MinaSocket` 是一个基于Apache Mina的Android长连接库,它提供了稳定、高效的网络通信功能,适用于需要实时数据交互的Android应用。通过使用这个库,开发者可以专注于业务逻辑,而无需过多关心...

    MinaDemo.zip SpringBoot集成Socket通讯

    现在我们来详细探讨如何在SpringBoot项目中集成Mina进行Socket通讯,并结合myBatis进行数据交互。 首先,我们需要在SpringBoot项目中引入Mina的相关依赖。在`pom.xml`文件中添加Mina的依赖项,例如: ```xml ...

    mina框架中socket使用,有服务端和客户端。

    MINA框架中的Socket服务端和客户端通过Socket接口实现数据的发送和接收,服务端创建监听Socket,等待客户端的连接请求;客户端则通过Socket连接到服务端,进行数据交互。 3. **服务端实现**:在MINA中,服务端通常...

    网络编程(socket、NIO、mina)---demo

    总结来说,这个"网络编程(socket、NIO、mina)---demo"涵盖了网络编程的基础与进阶,从基础的Socket通信,到提高性能的NIO,再到高级的Mina框架,这些都是开发分布式系统、网络服务和实时通信应用不可或缺的技术。...

    apache Mina和Flex as3.0 交互

    总结起来,Apache Mina和Flex AS3.0的交互涉及到网络通信、数据交换、服务端和客户端API的使用、事件驱动编程以及安全性与性能优化等多个方面。这种交互方式为开发高效、功能丰富的跨平台应用程序提供了可能,使...

    mina框架中socket应用的简单小项目,包含了所需jar

    4. **MINA的事件驱动模型**:MINA使用了事件驱动模型,通过监听和响应事件(如连接建立、数据到达、连接关闭等)来处理网络交互,这种模型使代码更简洁,易于理解和维护。 5. **项目结构**:通常,一个基于MINA的...

    利用AsyncSocket与后台数据交互

    在本文中,我们将深入探讨如何利用`AsyncSocket`与后台数据进行交互,以及它在实际应用中的关键知识点。 1. **AsyncSocket介绍**: `AsyncSocket`是一个异步的TCP套接字库,它在GCD(Grand Central Dispatch)的...

    原创nio socket mina+javascript+flash实现commet长连接网页聊天室

    "原创nio socket mina+javascript+flash实现commet长连接网页聊天室"揭示了一个基于Java NIO(Non-blocking I/O)的Socket通信框架Mina与JavaScript、Flash技术结合,实现COMET(Comet是使服务器向浏览器推送数据的...

    Mina客户端服务器Demo

    在Mina中,客户端和服务器的交互基于事件驱动模型,使得处理网络连接变得高效且易于维护。 Mina的核心概念包括: 1. **Session**: 在Mina中,Session代表一个连接。它封装了网络连接的细节,如网络套接字,并提供...

    Mina Server调试工具

    2. **会话跟踪**:能够追踪服务器上的各个会话,查看会话状态、读写数据以及相关的事件记录,帮助开发者了解服务器与客户端之间的交互过程。 3. **日志分析**:提供日志查看功能,便于开发者分析服务器运行时的日志...

    Mina通信Demo

    这意味着我们可以构建Android设备之间的点对点通信,或者让Android设备与传统服务器进行交互。 **3. TCP/IP和Socket通信** TCP/IP是互联网通信的基础,由应用层、传输层、网络层和数据链路层组成。TCP是传输层的一...

    MiNA框架新人指导

    这些框架被广泛应用于支付平台与银行之间的通信,例如支付宝与各大银行的交互过程中。尽管深入理解SOCKET或者HTTP协议的具体细节并不是必须的,但掌握这两个框架的基本使用方法对于从事此类项目的开发者而言至关重要...

    MIna中转服务

    `Minaclient`是Mina框架的客户端组件,负责与中转服务器建立连接和发送数据。它提供了一系列接口和类,如`IoSession`代表一个网络连接,`FilterChain`处理数据过滤,`ProtocolCodecFactory`实现数据编码解码等。...

    jbpm4.3 流程申请(mina通信)

    在提供的压缩包文件中,"clientJbpmDemo"可能是示例客户端程序,展示了如何使用Mina框架与jbpm4.3服务端交互。这个客户端可能包含配置文件(如XML配置)、Mina相关的类(如服务发现、会话管理和编码解码器)以及业务...

    mina网络通信实例

    MINA采用了NIO(Non-blocking I/O)模式,它与传统的BIO(Blocking I/O)模式不同,BIO在等待数据读写时会阻塞线程,而NIO则允许线程在没有数据可读写时继续执行其他任务,极大地提高了系统资源的利用率和吞吐量。...

    Mina文件及字符串传输

    标题中的"Mina文件及字符串传输"指的是使用Apache Mina框架进行数据交互的过程,包括发送和接收字符串请求以及传输文件。这一过程通常涉及到网络编程中的TCP/IP协议,因为Mina支持基于TCP的传输层通信。 首先,让...

    mina服务端例子

    运行这个例子,你需要配置正确端口,启动服务端,并通过一个简单的Socket客户端进行测试交互。调试时,可以观察日志输出,理解数据传输过程,以及过滤器和协议处理器是如何工作的。 6. **扩展与优化**: - 可以...

Global site tag (gtag.js) - Google Analytics