`

mina 传输java对象

    博客分类:
  • mina
阅读更多
mina client和server端传输和接收java对象,是java序列化和反序列化的过程。
mina-core包中有对这一块encoder-decoder的编解码类。
ObjectSerializationCodecFactory是工厂类,在client和server端配置coder filter时使用到。ObjectSerializationEncoder是序列化编码类,ObjectSerializationDecoder是序列化解码类

先看运行代码

server端
		IoAcceptor accepter = new NioSocketAcceptor();
		ProtocolCodecFilter coderFilter = 
	       //ObjectSerializationCodecF
		new ProtocolCodecFilter(new ObjectSerializationCodecFactory());
		accepter.getFilterChain().addLast("a", new LoggingFilter());
		accepter.getFilterChain().addLast("b",coderFilter);
		
		accepter.setHandler(new ObjectServerHandler());
		
		accepter.getSessionConfig().setReadBufferSize(2048);
		accepter.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
		accepter.bind(new InetSocketAddress(8484));

传输的简单java对象:
public class SimpleObj implements Serializable {

	/****/
	private static final long serialVersionUID = 8217287396365894807L;
	
	private String name;
	private String count;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getCount() {
		return count;
	}
	public void setCount(String count) {
		this.count = count;
	}
}


server端handler
public class ObjectServerHandler extends IoHandlerAdapter{
	
    @Override
    public void exceptionCaught( IoSession session, Throwable cause ) throws Exception
    {
        cause.printStackTrace();
        session.close(true);
    }
    @Override
    public void messageReceived( IoSession session, Object message ) throws Exception
    {
    	SimpleObj obj = (SimpleObj) message;
    	System.out.println(obj.getName()+":"+obj.getCount());
        session.write(obj);
    }
}


client端handler
public class ObjectClientHandler extends IoHandlerAdapter {
	private SimpleObj obj;
	
	public ObjectClientHandler(SimpleObj obj){
		this.obj = obj;
	}
	@Override
	public void sessionOpened(IoSession session) throws Exception {
		session.write(obj);
	}
	
	@Override
	public void messageReceived(IoSession session, Object message)
			throws Exception {
		System.out.println(message.toString());
	}
	
	@Override
	public void exceptionCaught(IoSession session, Throwable cause)
			throws Exception {
		session.close(true);
	}
}


client端
		NioSocketConnector connector = new NioSocketConnector();
		connector.setConnectTimeoutMillis(20000);
		connector.getFilterChain().addLast("codes", new ProtocolCodecFilter(
				new ObjectSerializationCodecFactory()));
		SimpleObj obj = new SimpleObj();
		obj.setName("bird");
		obj.setCount("7");
		connector.setHandler(new ObjectClientHandler(obj));
		
		IoSession session = null;
		ConnectFuture future = connector.connect(new InetSocketAddress("localhost", 8484));
		future.awaitUninterruptibly();
		session = future.getSession();
		session.getCloseFuture().awaitUninterruptibly();
		connector.dispose();


先启动server端服务,运行client端,server端就可收到传输的object。打印出bird:7


ObjectSerializationEncoder的encoder方法是序列化开始
org.apache.mina.filter.codec.serialization.ObjectSerializationEncoder
    public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {
     //没序列化,直接抛异常
        if (!(message instanceof Serializable)) {
            throw new NotSerializableException();
        }

        IoBuffer buf = IoBuffer.allocate(64);
        buf.setAutoExpand(true);
	//A 将Object序列化后字节内容填充到buffer内
        buf.putObject(message);
	//对象序列化后字节长度,大于最大值就抛异常,一般应该没这么大
	//maxObjectSize = Integer.MAX_VALUE; 
        int objectSize = buf.position() - 4;
        if (objectSize > maxObjectSize) {
            throw new IllegalArgumentException("The encoded object is too big: " + objectSize + " (> " + maxObjectSize
                    + ')');
        }

        buf.flip();
        out.write(buf);
    }


A处方法源码 org.apache.mina.core.buffer.AbstractIoBuffer
   public IoBuffer putObject(Object o) {
        int oldPos = position();
        skip(4); // 前4个长度先跳过,预留存储对象长度
        try {
            ObjectOutputStream out = new ObjectOutputStream(asOutputStream()//B,下面介绍) {
	    //重写了ObjectOutputStream的一个方法,不知道干什么用,
                @Override
                protected void writeClassDescriptor(ObjectStreamClass desc) throws IOException {
                    try {
                        Class<?> clz = Class.forName(desc.getName());
                        if (!Serializable.class.isAssignableFrom(clz)) { // NON-Serializable class
                            write(0);
                            super.writeClassDescriptor(desc);
                        } else { // Serializable class
                            write(1);
                            writeUTF(desc.getName());
                        }
                    } catch (ClassNotFoundException ex) { // Primitive types
                        write(0);
                        super.writeClassDescriptor(desc);
                    }
                }
            };
	    //和普通的java序列化一样,调用writeObject方法,java序列化前面文章有说过
            out.writeObject(o);
            out.flush();
        } catch (IOException e) {
            throw new BufferDataException(e);
        }

        // 填写前面预留的长度位
        int newPos = position();//当前position
        position(oldPos);//position标到开始位0
        putInt(newPos - oldPos - 4);//将object字节长度写入
        position(newPos);//postion到buffer的结尾
        return this;
    }


B处 asOutputStream()方法,就是实例化一个OutputStream,
两个写方法都是把内容放到IoBuffer里。
后续的Stream包装类,也就是ObjectOutputStream不管是writeShort,writeUTF等等也好,
最后都是调用这两个方法,所以上面的writeObject最后都是把object的内容写到了
IoBuffer里
    public OutputStream asOutputStream() {
        return new OutputStream() {
            @Override
            public void write(byte[] b, int off, int len) {
                AbstractIoBuffer.this.put(b, off, len);
            }

            @Override
            public void write(int b) {
                AbstractIoBuffer.this.put((byte) b);
            }
        };
    }


所以encode完后,传到server端的buffer内容
buffer=4个长度位+object序列化后的字节内容(序列化稍微差别,上面重写了个方法)

C处out方法源码
org.apache.mina.filter.codec.AbstractProtocolEncoderOutput

 
  public void write(Object encodedMessage) {
        if (encodedMessage instanceof IoBuffer) {
            IoBuffer buf = (IoBuffer) encodedMessage;
            if (buf.hasRemaining()) {
                messageQueue.offer(buf);
            } else {
                throw new IllegalArgumentException("buf is empty. Forgot to call flip()?");
            }
        } else {
            messageQueue.offer(encodedMessage);
            buffersOnly = false;
        }
    }

下面看server端解码:
org.apache.mina.filter.codec.serialization.ObjectSerializationDecoder

    protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
	//不足4个长度就直接不处理了,前面encode的过程肯定>4
        if (!in.prefixedDataAvailable(4, maxObjectSize)) {
            return false;
        }
	//AA 首先从buffer里吧序列化的对象读出来,反序列化
	//依次读取出来
        out.write(in.getObject(classLoader));
        return true;
    }

AA处getObject方法源码
    public Object getObject(final ClassLoader classLoader) throws ClassNotFoundException {
        if (!prefixedDataAvailable(4)) {
            throw new BufferUnderflowException();
        }
	//读取一个int,也就是读取前面encode的标示位
        int length = getInt();
        if (length <= 4) {
            throw new BufferDataException("Object length should be greater than 4: " + length);
        }

        int oldLimit = limit();
        limit(position() + length);
        try {
            ObjectInputStream in = new ObjectInputStream(asInputStream()//BB) {
		//略去两个重写ObjectInputStream方法
            };
	    //和普通java反序列化一样调用ObjectInputStream.readObject()方法
            return in.readObject();
        } catch (IOException e) {
            throw new BufferDataException(e);
        } finally {
            limit(oldLimit);
        }
    }


  BB处源码org.apache.mina.core.buffer.AbstractIoBuffer
    也是从buffer中读取序列化内容

       public InputStream asInputStream() {
        return new InputStream() {
            @Override
            public int available() {
                return AbstractIoBuffer.this.remaining();
            }

            @Override
            public synchronized void mark(int readlimit) {
                AbstractIoBuffer.this.mark();
            }

            @Override
            public boolean markSupported() {
                return true;
            }

            @Override
            public int read() {
                if (AbstractIoBuffer.this.hasRemaining()) {
                    return AbstractIoBuffer.this.get() & 0xff;
                }

                return -1;
            }

            @Override
            public int read(byte[] b, int off, int len) {
                int remaining = AbstractIoBuffer.this.remaining();
                if (remaining > 0) {
                    int readBytes = Math.min(remaining, len);
                    AbstractIoBuffer.this.get(b, off, readBytes);
                    return readBytes;
                }

                return -1;
            }

            @Override
            public synchronized void reset() {
                AbstractIoBuffer.this.reset();
            }

            @Override
            public long skip(long n) {
                int bytes;
                if (n > Integer.MAX_VALUE) {
                    bytes = AbstractIoBuffer.this.remaining();
                } else {
                    bytes = Math.min(AbstractIoBuffer.this.remaining(), (int) n);
                }
                AbstractIoBuffer.this.skip(bytes);
                return bytes;
            }
        };
    }
0
0
分享到:
评论

相关推荐

    mina传输对象的示例

    在标题和描述中提到的“mina传输对象的示例”指的是如何在Mina框架下处理和传输自定义的数据对象。Mina允许开发者通过事件驱动和异步I/O模型来高效地构建网络服务。 Mina的核心组件包括: 1. **Session**: 表示...

    mina文件传输

    Mina(MINA,全称Java Minimal Asynchronous Network Library)是一个用Java开发的网络通信框架,主要用于简化网络应用的开发,尤其是TCP和UDP协议的应用。它提供了高度抽象的API,使得开发者可以更专注于业务逻辑,...

    java-mina通信框架详解.docx

    它提供了JAVA对象的序列化和虚拟机内部通信的功能,使得开发者能够迅速构建高性能、高可扩展性的网络应用。Mina的核心特性是其事件驱动、异步(基于Java NIO)的编程模型,使得处理网络通信变得更加高效。 Mina分为...

    mina的高级使用,mina文件图片传送,mina发送文件,mina报文处理,mina发送xml和json

    Mina可以通过集成如JAXB(Java Architecture for XML Binding)或Jackson这样的库,将XML和JSON文档转换为字节流进行传输。同样,接收端可以反向操作,将接收到的字节流转回XML或JSON对象。这样,Mina就能方便地处理...

    java mina组合包

    Java Mina是一个高性能、异步事件驱动的网络应用程序框架,主要用于简化开发服务器端和客户端的网络应用。这个“java mina组合包”看起来包含了Mina库的所有必要组件和可能的扩展,为开发者提供了完整的开发环境。 ...

    java mina框架全套

    Mina在Java NIO(非阻塞I/O)的基础上构建,支持多种传输层协议,如TCP、UDP、SSL/TLS等,并且能够处理大量的并发连接。 Mina的核心组件包括: 1. **Session**:Mina中的会话接口,代表了网络连接。每个网络连接都...

    websocket+java服务器(mina)

    Mina(Java Multithreaded Network Application Framework)是一个用Java编写的网络应用框架,它提供了高度可扩展性和性能,适用于多种网络协议,包括TCP和UDP。Mina为开发者提供了一种抽象层,简化了网络编程的复杂...

    JAVA mina 框架源码

    5. **Protocol Codec**: Mina提供了一套编码解码机制,方便用户将业务对象转化为字节流在网络中传输,反之亦然。 深入研究Mina源码,我们可以学习到以下关键知识点: 1. **事件驱动模型**:Mina基于事件驱动模型,...

    Java springboot 整合mina 框架,nio通讯基础教程,mina框架基础教程.zip

    Buffer(缓冲区),存储和传输数据的主要对象。学习Java NIO,你需要理解这些核心概念,并熟练运用它们来构建高性能的网络应用程序。 Mina框架是一个轻量级的网络通信框架,基于Java NIO构建,它简化了网络编程的...

    java客户端socket与mina服务端通信

    Java客户端Socket与Mina服务端通信是网络编程中常见的应用场景,尤其在开发分布式系统或实时数据传输时。这里我们将深入探讨这两个技术,并了解如何通过它们建立保持长连接的通信。 首先,Socket是Java中用于实现...

    java 实现的mina server client完全能用的

    3. **ProtocolDecoder/Encoder**:Mina提供了编码器和解码器接口,用于将应用程序对象转换为字节流(或反之),以便在网络上传输。例如,你可以使用XMLDecoder和XMLEncoder来处理XML消息。 4. **Filter Chain**:...

    websocket+java服务器(mina)

    在Mina中,数据传输通常通过IoSession对象来完成,它可以提供读写操作,以及获取连接状态等信息。对于WebSocket消息,你需要解析和封装成特定的WebSocketFrame,然后再通过IoSession发送出去。同样,接收到的...

    mina自定义编解码器详解

    在mina框架中,编解码器(Codec)扮演着至关重要的角色,它负责将应用层的数据转换为网络传输的字节流,以及将接收到的字节流还原为应用程序可以理解的对象。对于初学者来说,理解和编写自定义的编解码器可能会遇到...

    Java mina2源码

    3. **Buffer**:Mina2使用Buffer对象存储网络数据,它提供了读写操作,支持高效地处理字节流。Buffer的容量、位置和限制等属性,使得在处理大数据时更加灵活。 4. **ProtocolCodec**:Mina2的编码解码机制,允许...

    Mina文件及字符串传输

    这个字符串可以通过Mina的WriteRequest对象发送,WriteRequest通常包含一个ByteBuffer或一个可序列化的对象。Mina会自动处理字符串到字节的转换,然后通过网络发送给服务器。 服务端接收到连接请求后,会创建一个...

    mina 集成spring 传输文件和文本

    这个监听器应具备处理两种不同数据类型的能力,可能需要使用Mina的Session对象和Filter链。 6. **协议设计**:设计一个自定义协议来区分文件和文本数据。这可能包括特定的起始和结束标记,或者预定义的命令结构。 ...

    Android Java Socket框架 Mina2.0

    **Android Java Socket框架 Mina2.0** Mina2.0是Apache软件基金会的一个开源项目,它是一个网络通信框架,主要应用于Java环境。Mina旨在简化高性能、高可用性和高可扩展性的网络应用开发,特别适合于处理大量并发...

    高性能网络架构Mina框架 下载

    Session是Mina中表示客户端连接会话的对象,它封装了连接状态和数据传输的相关信息。每个连接都有一个对应的Session对象,通过它可以获取和设置连接属性、发送消息等。 ##### 3.4 Buffer Buffer是Mina中用于存储和...

    mina高性能Java网络框架.rar

    Mina最主要的工作就是把底层传输的字节码转换为Java对象,提供给应用程序;或者把应用程序返回的结果转换为字节码,交给底层传输。 总结: 1.默认使用的是JAVA NIO 作为底层支持)操作的编程模型 2.主要屏蔽了...

    MinaUdp通信对象传输例子

    **Mina UDP通信对象传输详解** Apache Mina (Minimum Asynchronous Network Application Platform) 是一个高度可扩展和高性能的网络应用程序框架,它简化了创建网络服务和应用的过程,无论是基于TCP还是UDP协议。在...

Global site tag (gtag.js) - Google Analytics