mina多文件传输

来源:互联网 发布:织梦cmspath 编辑:程序博客网 时间:2024/04/28 14:13

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

总的结构如下:

服务器部分:

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 stubsuper.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); //设置连接超时msconnector.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{@Overridepublic ProtocolDecoder getDecoder(IoSession session) throws Exception {// TODO Auto-generated method stubreturn super.getDecoder(session);}@Overridepublic ProtocolEncoder getEncoder(IoSession session) throws Exception {// TODO Auto-generated method stubreturn 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 stubContext 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