日期:2014-05-17  浏览次数:21111 次

Apache mina设置默认的write和read buffer,以及奥秘
最近在做一个项目,用到mina,但是对于mina发送文件,或者报文分包发送有很多不明白的。查看了很多资料,其中找到一位仁兄的发送文件的代码,是一个客户端上传文件到服务器的例子。

作为本文的引子:

客户端程序

package test;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

import org.apache.mina.core.RuntimeIoException;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

public class ClientMain {

	/**
	 * @author daijun ,Nov 26, 2009
	 * @param args
	 * @throws InterruptedException
	 * @throws IOException
	 */
	public static void main(String[] args) throws InterruptedException, IOException {
		try {
			NioSocketConnector connector = new NioSocketConnector();
			DefaultIoFilterChainBuilder chain = connector.getFilterChain();
			connector.setHandler(new FileSenderHandler());
			ConnectFuture connectFuture = connector.connect(new InetSocketAddress("127.0.0.1", 3333));
			IoSession session = null;
			for (;;) {
				try {
					ConnectFuture future = connector.connect(new InetSocketAddress("localhost", 3333));
					future.awaitUninterruptibly();
					session = future.getSession();
					break;
				} catch (RuntimeIoException e) {
					System.err.println("Failed to connect.");
					e.printStackTrace();
					Thread.sleep(5000);
				}
			}
			File f = new File("e:/20100425171.jpg");
			// System.out.println(f.length());
			FileInputStream fin = new FileInputStream(f);
			FileChannel fc = fin.getChannel();
			ByteBuffer bb = ByteBuffer.allocate(2048 * 1000);
			boolean flag = true;
			while (true) {
				// 不间断发送会导致buffer异常
				if (!flag) {
					Thread.sleep(1000);
				}
				bb.clear();
				int i = fc.read(bb);
				System.out.println(i);
				if (i == -1) {
					System.out.println("exit");
					break;
				}
				// 包装成自己的iobuffer
				IoBuffer ib = IoBuffer.wrap(bb);
				bb.flip();
				session.write(ib);
				flag = false;
			}
			session.close(true);
			
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}
}



客户端的handler,其实没啥用,就是那位仁兄的代码

package test;

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

public class FileSenderHandler extends IoHandlerAdapter {
	@Override
	public void messageReceived(IoSession session, Object message) throws Exception {
	}

	@Override
	public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
		session.close(true);
	}
	@Override
	public void messageSent(IoSession session, Object message) throws Exception {
		System.out.println("hidsda");
		super.messageSent(session, message);
	}

}



Server端代码:
package test;

import java.io.IOException;
import java.net.InetSocketAddress;

import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.transport.socket.SocketAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

public class ServerMain {

	/**
	 * @author daijun ,Nov 26, 2009
	 * @param args
	 * @throws IOException
	 */
	public static void main(String[] args) throws IOException {
		SocketAcceptor acceptor = new NioSocketAcceptor();
		DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
		acceptor.setHandler(new FileReceiveHandler());
		acceptor.bind(new InetSocketAddress(3333));
	}

}



Server端Handler:
package test;

import java.io.FileOutputStream;
import java.nio.channels.FileChannel;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.m