mina多文件传输

参考了一些示例代码,但是后面碰到一个坑爹的问题,服务器给客户端返回消息和之前的编码解码过程发生冲突。。。。

总的结构如下:

服务器部分:

package com.blazefire.server;

import java.net.InetSocketAddress;

import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

import com.blazefire.util.MathProtocolCodecFactory;

public class Server {
	public void bindServer()  throws Exception{
		IoAcceptor acceptor=new NioSocketAcceptor(); 
		acceptor.getSessionConfig().setReadBufferSize(1024*2); 
		acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE,10); 
		acceptor.getFilterChain().addLast("codec",
		new ProtocolCodecFilter(new MathProtocolCodecFactory(true))); 
		acceptor.setHandler(new ServerHandler());
		acceptor.bind(new InetSocketAddress(8080)); 
		System.out.println("server ok");
	}
	public static void main(String[] args) {
		Server server = new Server();
		try {
			server.bindServer();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

package com.blazefire.server;

import java.io.File;
import java.io.FileOutputStream;

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

import com.blazefire.bean.BaseMessage;
import com.blazefire.bean.FileBean;
import com.blazefire.client.ClientHandler;
import com.blazefire.util.FileHelper;

public class ServerHandler extends IoHandlerAdapter{

	public static Logger logger = Logger.getLogger(ServerHandler.class);
	public boolean tanfer = false;
	public void sessionCreated(IoSession session) throws Exception {
		super.sessionCreated(session);
	}

	public void sessionOpened(IoSession session) throws Exception {
	}
	/**
	 * 服务器接收到消息
	 * */
	public void messageReceived(IoSession session, Object message)
			throws Exception {
		// TODO Auto-generated method stub
		super.messageReceived(session, message);
		BaseMessage baseMessage = (BaseMessage) message;
		FileBean bean = (FileBean) baseMessage.getData();
		System.out.println(bean.getFileName());
	    FileOutputStream os = new FileOutputStream("g:\\logget\\"+bean.getFileName());  		
		os.write(bean.getFileContent());
		os.close();
		Long endTime = System.currentTimeMillis();
		System.out.println(endTime);
		BaseMessage bm = new BaseMessage();
		bm.setDataType(1);
		FileBean b = new FileBean();
		File f = new File("e:\\t.txt");
		b.setFileName(f.getName());
		b.setFileSize((int)f.length());
		FileHelper helper =new FileHelper();
		b.setFileContent(helper.getContent(f));
		bm.setData(b);
		session.write(bm);
	}


	public void exceptionCaught(IoSession session, Throwable cause)
			throws Exception {
		super.exceptionCaught(session, cause);
	}
}

客户端:

package com.blazefire.client;

import java.net.InetSocketAddress;

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.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

import com.blazefire.util.MathProtocolCodecFactory;

public class Client {
	
	public IoSession creatClient(){
		IoConnector connector=new NioSocketConnector();   //连接到端点,与服务器通信
		connector.setConnectTimeoutMillis(30000); 		//设置连接超时ms
		connector.getFilterChain().addLast("codec", 
		new ProtocolCodecFilter(new MathProtocolCodecFactory(false)));   //设置过滤器
		connector.setHandler(new ClientHandler());						//业务处理
		ConnectFuture future = connector.connect(new InetSocketAddress("127.0.0.1", 8080)); 
		// 等待是否连接成功,相当于是转异步执行为同步执行。 
		future.awaitUninterruptibly(); 
		// 连接成功后获取会话对象。 如果没有上面的等待, 由于connect()方法是异步的, session可能会无法获取。 
		IoSession session = null;
		try{
			session = future.getSession();		//获取连接操作的结果
		}catch(Exception e){
			e.printStackTrace();
		}
		return session;
	}
	public static void main(String[] args) {
//		for(int i=0;i<1;i++){
//		       new Thread(new Runnable() {
//				
//				@Override
//				public void run() {
//					Client client = new Client();
//					client.creatClient();
//					
//				}}).start();
//
//		    	try {
//					Thread.sleep(6000);
//				} catch (InterruptedException e) {
//					e.printStackTrace();
//				}
//		      } 
//		
		Client client = new Client();
		client.creatClient();
		
	}
}

package com.blazefire.client;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

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

import com.blazefire.bean.BaseMessage;
import com.blazefire.bean.FileBean;
import com.blazefire.server.ServerHandler;
import com.blazefire.util.BeanUtil;
import com.blazefire.util.FileHelper;

public class ClientHandler extends IoHandlerAdapter{
	public static Logger logger = Logger.getLogger(ClientHandler.class);
	private String[] str = null;
	/**
	 * 客户端接收到信息   消息被接收后调用
	 * */
	public void messageReceived(IoSession session, Object message)
			throws Exception {
		session.close(true);
		File ff = new File("g:\\logget\\");
		if((ff.list()).length<1000){
			Client client = new Client();
			client.creatClient();

		}
	}
	/*
	 * 连接已打开调用
	 * @see org.apache.mina.core.service.IoHandlerAdapter#sessionOpened(org.apache.mina.core.session.IoSession)
	 */
	public void sessionOpened(IoSession session) { 
		File fs = new File("g:\\logget\\");
		Long startTime=System.currentTimeMillis();
		String filepath = "e:\\sent\\";
		BaseMessage baseMessage = new BaseMessage();
		baseMessage.setDataType(BeanUtil.UPLOAD_FILE);
		FileBean bean = new FileBean();
		checkExist(filepath);
		File file = new File(filepath+str[0]);
		bean.setFileName(file.getName());
		bean.setFileSize((int)file.length());
		try {
			FileHelper helper =new FileHelper();
			bean.setFileContent(helper.getContent(file));
		} catch (Exception e) {
			e.printStackTrace();
		}
		baseMessage.setData(bean);
		session.write(baseMessage); 
	}

	private void checkExist(String filepath) {
		File file=new File(filepath);
		if (file.exists()) {//判断文件目录的存在
			if(file.isDirectory()){//判断文件的存在性      
				str = file.list();
			}else{
				System.out.println("文件不存在"  );      
				
			}
		}
	}
	/*
	 * 从一个I/O处理器线程调用时创建一个新的连接。
	 * @see org.apache.mina.core.service.IoHandlerAdapter#sessionCreated(org.apache.mina.core.session.IoSession)
	 */
	
	public void sessionCreated(IoSession session) throws Exception {
		super.sessionCreated(session);
	}
	
	
}

上面的服务器处理类中,关于返回信息的那部分是个败笔。。。。。

package com.blazefire.util;

import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolEncoder;
import org.apache.mina.filter.codec.demux.DemuxingProtocolCodecFactory;

import com.blazefire.bean.BaseMessage;

public class MathProtocolCodecFactory extends DemuxingProtocolCodecFactory{
	
	@Override
	public ProtocolDecoder getDecoder(IoSession session) throws Exception {
		// TODO Auto-generated method stub
		return super.getDecoder(session);
	}

	@Override
	public ProtocolEncoder getEncoder(IoSession session) throws Exception {
		// TODO Auto-generated method stub
		return super.getEncoder(session);
	}

	public MathProtocolCodecFactory(boolean server){
		if(server){
			super.addMessageDecoder(BaseMessageDecoder.class);
			super.addMessageEncoder(BaseMessage.class, BaseMessageEncoder.class);
		}else{
			super.addMessageDecoder(BaseMessageDecoder.class);
			super.addMessageEncoder(BaseMessage.class, BaseMessageEncoder.class);
		}
	}
}

编码和解码:

package com.blazefire.util;

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

import org.apache.log4j.Logger;
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;

import com.blazefire.bean.BaseMessage;
import com.blazefire.bean.FileBean;
import com.blazefire.server.ServerHandler;

public class BaseMessageDecoder  implements MessageDecoder {
	private AttributeKey CONTEXT = new AttributeKey(getClass(), "context");
	public static Logger logger = Logger.getLogger(BaseMessageDecoder.class);

	/**
	 * 是否适合解码
	 * */
	public MessageDecoderResult decodable(IoSession session, IoBuffer in) {
		// TODO Auto-generated method stub
		Context context = (Context) session.getAttribute(CONTEXT);
		if(context == null){
			context = new Context();
			context.dataType = in.getInt();
			if(context.dataType == BeanUtil.UPLOAD_FILE){
				context.strLength = in.getInt();
				context.byteStr = new byte[context.strLength];
				context.fileSize = in.getInt();
				context.byteFile = new byte[context.fileSize];
				session.setAttribute(CONTEXT, context);
				return MessageDecoderResult.OK;
			}else{
				return MessageDecoderResult.NOT_OK;
			}
		}else{
			if(context.dataType == BeanUtil.UPLOAD_FILE){
				return MessageDecoderResult.OK;
			}else{
				return MessageDecoderResult.NOT_OK;
			}
		}
	}

	/**
	 * 数据解码
	 * */
	public MessageDecoderResult decode(IoSession session, IoBuffer in,
			ProtocolDecoderOutput outPut) throws Exception {
		// TODO Auto-generated method stub
//		logger.info("=====start decode");
		Context context = (Context) session.getAttribute(CONTEXT);
		if(!context.init){
			context.init = true;
			in.getInt();
			in.getInt();
			in.getInt();
		}
		byte[] byteFile = context.byteFile;
		int count = context.count;
		while(in.hasRemaining()){
			byte b = in.get();
			if(!context.isReadName){
				context.byteStr[count] = b;
				if(count == context.strLength-1){
					context.fileName = new String(context.byteStr,BeanUtil.charset);
//					System.out.println(context.fileName);
					count = -1;
					context.isReadName = true;
				}
			}
			if(context.isReadName && count != -1){
				byteFile[count] = b;
			}
		//	byteFile[count] = b;
			count++;
		}
		context.count = count;
		System.out.println("count:"+count);
		System.out.println("context.fileSize:"+context.fileSize);
		session.setAttribute(CONTEXT, context);
		if(context.count == context.fileSize){
			BaseMessage message = new BaseMessage();
			message.setDataType(context.dataType);
			FileBean bean = new FileBean();
			bean.setFileName(context.fileName);
			bean.setFileSize(context.fileSize);
			bean.setFileContent(context.byteFile);
			message.setData(bean);
			outPut.write(message);
			context.reset();
		}
		return MessageDecoderResult.OK;
	}

	/**
	 * 
	 * */
	public void finishDecode(IoSession session, ProtocolDecoderOutput outPut)
			throws Exception {
		// TODO Auto-generated method stub
//		logger.info("decode sucess========="); 
	}
	private class Context{
		public int dataType;
		public byte[] byteFile;
		public int count;
		public int strLength;
		public boolean isReadName;
		public int fileSize;
		public byte[] byteStr;
		public String fileName;
		public boolean init = false;
		
		public void reset(){
			dataType = 0;
			byteFile = null;
			count = 0;
			strLength = 0;
			isReadName = false;
			fileSize = 0;
			byteStr = null;
			fileName = null;
			
		}
	}


}

package com.blazefire.util;

import java.nio.charset.Charset;

import org.apache.log4j.Logger;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;
import org.apache.mina.filter.codec.demux.MessageEncoder;

import com.blazefire.bean.BaseMessage;
import com.blazefire.bean.FileBean;

public class BaseMessageEncoder implements MessageEncoder<BaseMessage> {
	public static Logger logger = Logger.getLogger(BaseMessageEncoder.class);

	/**
	 * 基本信息编码
	 * */
	public void encode(IoSession session, BaseMessage message,ProtocolEncoderOutput outPut) throws Exception {
		// TODO Auto-generated method stub
//		logger.info("=====encode start");
		IoBuffer buffer = IoBuffer.allocate(1024).setAutoExpand(true); 
		buffer.putInt(message.getDataType());
		FileBean bean = (FileBean) message.getData();
		byte[] byteStr = bean.getFileName().getBytes(BeanUtil.charset);
		buffer.putInt(byteStr.length);
		buffer.putInt(bean.getFileSize());
		buffer.put(byteStr);
		buffer.put(bean.getFileContent());
		buffer.flip();
		outPut.write(buffer);
//		logger.info("=====encode end");
	}

}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值