参考了一些示例代码,但是后面碰到一个坑爹的问题,服务器给客户端返回消息和之前的编码解码过程发生冲突。。。。
总的结构如下:
服务器部分:
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");
}
}