原文出处:https://blog.youkuaiyun.com/cgwcgw_/article/details/18402769
本文记录的是采用mima实现客户端和服务端的通信,下面是具体的代码实现步骤:
服务端
package my.mina;
import org.apache.log4j.Logger;
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.textline.LineDelimiter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
/**
* @author: Linchong
* @Date: 2018/7/10 15:06
* @Description:
*/
public class Demo1Server {
private static Logger logger = Logger.getLogger(Demo1Server.class);
private static final int PORT = 3005;
public static void main(String[] args) {
IoAcceptor acceptor = null;
try {
// 1创建一个非阻塞的server端的Socket
acceptor = new NioSocketAcceptor();
// 2设置过滤器(使用Mina提供的文本换行符编解码器)
acceptor.getFilterChain().addLast("codec",new ProtocolCodecFilter(new TextLineCodecFactory(
Charset.forName("UTF-8"),LineDelimiter.WINDOWS.getValue(),LineDelimiter.WINDOWS.getValue()
)));
// 3设置读取数据的缓冲区大小
acceptor.getSessionConfig().setReadBufferSize(2048);
// 4读写通道10秒内无操作进入空闲状态
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE,10);
// 5绑定逻辑处理器
acceptor.setHandler(new Demo1ServerHandler());
// 6绑定端口
acceptor.bind(new InetSocketAddress(PORT));
logger.info("服务器启动,port : "+PORT);
} catch (IOException e) {
logger.info("服务器启动失败...");
e.printStackTrace();
}
}
}
服务端处理器
package my.mina;
import org.apache.log4j.Logger;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import java.util.Date;
/**
* @author: Linchong
* @Date: 2018/7/10 15:20
* @Description:
*/
public class Demo1ServerHandler extends IoHandlerAdapter {
private static Logger logger = Logger.getLogger(Demo1ServerHandler.class);
private static final String BYE = "bye";
@Override
public void messageReceived(IoSession session, Object message) throws Exception {
String msg = message.toString();
logger.info("Server:"+msg);
if(BYE.equalsIgnoreCase(msg)) {
session.close();
}
Date date = new Date();
session.write(date);
}
@Override
public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
super.exceptionCaught(session, cause);
}
}
客户端
package my.mina;
import org.apache.log4j.Logger;
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.textline.LineDelimiter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
/**
* @author: Linchong
* @Date: 2018/7/10 15:35
* @Description:
*/
public class Demo1Client {
private static final Logger logger = Logger.getLogger(Demo1Client.class);
private static final String ADDRESS = "127.0.0.1";
private static final int PORT = 3005;
public static void main(String[] args) {
IoConnector connector = null;
// 创建一个非阻塞的客户端程序
connector = new NioSocketConnector();
// 设置链接超时时间
connector.setConnectTimeoutMillis(10000L);
// 添加过滤器
connector.getFilterChain().addLast("codec",new ProtocolCodecFilter(new TextLineCodecFactory(
Charset.forName("UTF-8"),LineDelimiter.WINDOWS.getValue(),LineDelimiter.WINDOWS.getValue()
)));
// 添加业务逻辑处理器类
connector.setHandler(new Demo1ClientHandler());
IoSession session = null;
try {
//创建连接
ConnectFuture future = connector.connect(new InetSocketAddress(ADDRESS,PORT));
//等待连接创建完成
future.awaitUninterruptibly();
//获得session
session = future.getSession();
//发送消息
session.write("Mima我喜欢你");
} catch (Exception e) {
logger.info("客户端连接异常...");
e.printStackTrace();
}
// 等待连接断开
session.getCloseFuture().awaitUninterruptibly();
//该方法通过调用ExecutorService的shutdown()方法停止业务处理线程,并设置内部disposed标志位标识需要停止连接管理器;Worker线程通过该标识停止。
connector.dispose();
}
}
客户端处理器
package my.mina;
import org.apache.log4j.Logger;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
/**
* @author: Linchong
* @Date: 2018/7/10 15:41
* @Description:
*/
public class Demo1ClientHandler extends IoHandlerAdapter {
private static final Logger logger = Logger.getLogger(Demo1ClientHandler.class);
@Override
public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
super.exceptionCaught(session, cause);
}
@Override
public void messageReceived(IoSession session, Object message) throws Exception {
String msg = message.toString();
logger.info("Client:"+msg);
}
}
总结
1、服务端
通过IoAcceptor的子类NioSocketAcceptor创建服务端socket,然后对它进行一系列的设置,例如设置过滤器(很多时候我们都需要自定义过滤器),设置逻辑处理器(创建一个IoHandler的子类,我们一般是继承IoHandler的子类IoHandlerAdapter,然后重写它的方法),读取缓存大小,绑定端口号等
2、客户端
和服务端很多地方相似,客户端是通过IoConnector的子类NioSocketConnector创建客户端socket,然后进行一系列的设置,例如设置链接超时时间、过滤器、逻辑处理类等,然后通过socket创建连接,通过session发送消息。
最后附上IoService接口主要继承结构图: