我在第一章的时候,就说了,socket 是一种很少用的东西了,而且又是阻塞性的,所以原作者,就对于socket进行了第三次封装,mina就出现了。不用猜 也是Apache出品的..... 第二次是NIO 用法太过复杂,所以进行了第三次封装。
服务器端代码编写
package com.xiaoxin.socketServer;
import java.io.IOException;
import java.net.InetSocketAddress;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
public class MinaServer {
public static void main(String[] args) {
//
try {
//服务器
NioSocketAcceptor acceptor=new NioSocketAcceptor();
//消息处理
acceptor.setHandler(new MyServerHandler());
//拦截器设置 字符串加减码
acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new MyTextLineFactory()));
//监听端口
acceptor.bind(new InetSocketAddress(9898));
//设置发送和接收 3秒没有反应进入空闲状态
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 3000);
} catch (IOException e) {
e.printStackTrace();
}
}
}
对于信息加密,我们自己处理,不用原生的。
package com.xiaoxin.socketServer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolEncoder;
public class MyTextLineFactory implements ProtocolCodecFactory {
/**
* 加密
*/
private MyTextLineEncode encode;
/**
* 解密
*/
private MyTextLineDecode decode;
public MyTextLineFactory() {
encode=new MyTextLineEncode();
decode=new MyTextLineDecode();
}
@Override
public ProtocolDecoder getDecoder(IoSession arg0) throws Exception {
return decode;
}
@Override
public ProtocolEncoder getEncoder(IoSession arg0) throws Exception {
return encode;
}
}
package com.xiaoxin.socketServer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoder;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;
public class MyTextLineEncode implements ProtocolEncoder {
@Override
public void dispose(IoSession arg0) throws Exception {
}
@Override
public void encode(IoSession session, Object message, ProtocolEncoderOutput out)
throws Exception {
//只能传输String类型
String s=null;
if (message instanceof String) {
s=(String) message;
}
//设置编码
if (s!=null) {
CharsetEncoder charsetEncoder=(CharsetEncoder) session.getAttribute("ender");
if (charsetEncoder==null) {
charsetEncoder= Charset.defaultCharset().newEncoder();
session.setAttribute("ender");
}
//开启内存
IoBuffer ioBuffer = IoBuffer .allocate(s.length());
//扩展内存
ioBuffer.setAutoExpand(true);
ioBuffer.putString(s, charsetEncoder);
ioBuffer.flip();
out.write(ioBuffer);
}
}
}
package com.xiaoxin.socketServer;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
public class MyTextLineDecode implements ProtocolDecoder {
@Override
public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out)
throws Exception {
//开始位置
int startpotion = in.position();
while (in.hasRemaining()) {
byte b = in.get();
if (b=='\n') {
//记录下当前位置
int currntpotion = in.position();
int limit = in.limit();
in.position(startpotion);
in.limit(currntpotion);
//截取
IoBuffer slice = in.slice();
byte []dest=new byte[slice.limit()];
slice.get(dest);
String str=new String(dest);
out.write(str);
in.position(currntpotion);
in.limit(limit);
}
}
}
@Override
public void dispose(IoSession arg0) throws Exception {
}
@Override
public void finishDecode(IoSession arg0, ProtocolDecoderOutput arg1)
throws Exception {
}
}
客户端代码编写
package com.xiaoxin.client;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
public class MinaClient {
public static void main(String[] args) throws Exception {
//客户端
NioSocketConnector connector=new NioSocketConnector();
//消息处理
connector.setHandler(new MyClientHandler());
//过滤器
connector.getFilterChain().addLast("code", new ProtocolCodecFilter(new TextLineCodecFactory()));
//设置端口
ConnectFuture connect = connector.connect(new InetSocketAddress("127.0.0.1",9898));
//等待连接
connect.awaitUninterruptibly();
//得到IO流
IoSession session = connect.getSession();
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String inputContent;
while (!(inputContent=reader.readLine()).equals("bye")) {
session.write(inputContent);
}
}
}
消息处理
package com.xiaoxin.client;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
public class MyClientHandler extends IoHandlerAdapter {
@Override
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
System.out.println("exceptionCaught");
}
@Override
public void messageReceived(IoSession session, Object message)
throws Exception {
System.out.println("messageReceived");
}
@Override
public void messageSent(IoSession session, Object message) throws Exception {
super.messageSent(session, message);
System.out.println("messageSent");
}
@Override
public void sessionClosed(IoSession session) throws Exception {
super.sessionClosed(session);
System.out.println("sessionClosed");
}
@Override
public void sessionCreated(IoSession session) throws Exception {
System.out.println("sessionCreated");
}
@Override
public void sessionIdle(IoSession session, IdleStatus status)
throws Exception {
System.out.println("sessionIdle");
}
@Override
public void sessionOpened(IoSession session) throws Exception {
System.out.println("sessionOpened");
}
}