1.引入依赖
<!-- https://mvnrepository.com/artifact/org.apache.mina/mina-core -->
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-core</artifactId>
<version>2.0.7</version>
</dependency>
2.创建服务端
IoAcceptor acceptor = new NioSocketAcceptor();
TextLineCodecFactory factory = new TextLineCodecFactory(Charset.forName("UTF-8"));
factory.setDecoderMaxLineLength(Integer.MAX_VALUE);
acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(factory));
acceptor.getSessionConfig().setReadBufferSize(20480);
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 100);
acceptor.getFilterChain().addLast("threadPool", new ExecutorFilter(Executors.newCachedThreadPool()));
acceptor.setHandler(new DockHandler());
acceptor.bind(new InetSocketAddress(port));
log.info("=== TCP Server start on port " + port);
消息处理器IoHandlerAdapter实现类:
@Slf4j
public class DockHandler extends IoHandlerAdapter
{
@Override
public void messageReceived(IoSession session, Object message)
throws Exception
{
super.messageReceived(session, message);
String msg = (String)message;
log.info("收到消息:" + msg);
sockerHandlerService.dockSocketMessage(msg);
}
@Override
public void sessionCreated(IoSession session)
throws Exception
{
super.sessionCreated(session);
log.info("创建连接");
}
@Override
public void sessionOpened(IoSession session)
throws Exception
{
super.sessionOpened(session);
log.info("建立连接");
}
@Override
public void sessionClosed(IoSession session)
throws Exception
{
super.sessionClosed(session);
log.info("连接关闭");
}
@Override
public void sessionIdle(IoSession session, IdleStatus status)
throws Exception
{
super.sessionIdle(session, status);
log.info("重新连接");
}
@Override
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception
{
super.exceptionCaught(session, cause);
log.info("会话异常!");
if (session != null)
{
session.closeNow();
}
}
@Override
public void messageSent(IoSession session, Object message)
throws Exception
{
super.messageSent(session, message);
}
@Override
public void inputClosed(IoSession session)
throws Exception
{
super.inputClosed(session);
}
}
本文使用的Mina自带的基于文本的编解码器TextLineCodecFactory,根据回车换行(windows下是\r\n,linux下是\r)来断点传输数据,且在解码器中解决了半包粘包问题。
客户端程序参考另一篇:https://blog.csdn.net/qq_34928194/article/details/106387499
自定义编解码器:一个来自未来博文的url:Mina自定义解码器,解决半包粘包问题