因项目架构需求,需要开发一个Mina Tcp服务器。我的Mina服务器是Java winForm,这与在web项目使用会有少许不同。

1、Maven依赖

        <dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-core</artifactId>
<version>2.2.1</version>
</dependency>

2、开发网络数据包编/解码器(传输文本消息可以配置mina使用TextLineCodeFactory工厂类获取编/解码器),用于socket传输数据的过滤处理。本次开发Tcp服务器传输的是字节数据,并且自定义了通信的协议;所以编写了下面的编解码器及工厂类:

//解码器,用于解包socket接收的数据
public class TcpByteDecoder extends CumulativeProtocolDecoder {
/**
* 固定包头长度
*/
private static final int Package_Header_Length = 6; @Override
protected boolean doDecode(IoSession ioSession, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
if (Package_Header_Length < in.remaining()) { //缓冲区中的数据长度大于包头,说明可以尝试解码
//标记当前position,以便后继的reset操作能恢复position位置
in.mark();
//获取协议头的5、6字节对应的剩余包长度(协议格式固定为5、6字节存储的是一包数据后续剩余字节数量)
int len = in.getUnsignedShort(4);
if ((Package_Header_Length + len) > in.remaining()) {
//包头长度+包头内指明的后续字节长度>接收数据缓冲区数据长度,则说明接收数据缓冲区的数据还不够一包数据。重置position到操作前,继续接收数据
in.reset();
return false;
}
//创建byte数组,接收一包数据。一包数据的长度=包头字节数+包字节剩余字节数
byte[] msg = new byte[Package_Header_Length + len];
//获取缓冲区中的数据到数据包byte数组中
in.get(msg);
//将数据包byte数组输出后续过滤器或处理器
out.write(msg);
//读取包后,如果缓冲区还有数据且>包头
if (Package_Header_Length < in.remaining()) {
//返回ture,再次进行解包
return true;
}
}
return false;//返回false继续接收数据
}
}
//编码器,用于编码要发送出去的数据(程序上层应用数据格式为byte[],此处只将byte[]原样输出)
public class TcpByteEncoder extends ProtocolEncoderAdapter { @Override
public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {
byte[] data = (byte[])message;//获取要发送的数据
IoBuffer buf = IoBuffer.allocate(data.length).setAutoExpand(true);//准备一个大小与数据长度一样的输出缓冲区
buf.put(data);//将数据放入缓冲区
buf.flip();//固定数据
out.write(buf);//将缓冲区内容输出
}
}
//编解码器工厂
public class TcpProtocolCodecFactory implements ProtocolCodecFactory {
private TcpByteDecoder decoder;
private TcpByteEncoder encoder; public ModbusTcpProtocolCodecFactory() {
decoder = new TcpByteDecoder();
encoder = new TcpByteEncoder();
} @Override
public ProtocolEncoder getEncoder(IoSession ioSession) throws Exception {
return encoder;
} @Override
public ProtocolDecoder getDecoder(IoSession ioSession) throws Exception {
return decoder;
}
}

3、开发Mina事件处理程序

public class MinaClientHandler extends IoHandlerAdapter {
private String deviceNo; public MinaClientHandler(String deviceNo) {
this.deviceNo = deviceNo;
} @Override
public void sessionCreated(IoSession session) throws Exception {
super.sessionCreated(session);
} @Override
public void sessionOpened(IoSession session) throws Exception {
super.sessionOpened(session);
} @Override
public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
if (session.isConnected()) {
session.closeNow();
}
super.exceptionCaught(session, cause);
} @Override
public void messageReceived(IoSession session, Object message) throws Exception {
//此处获取到的message,实际就是在上述解码器中out.write的内容
       byte[] data = (byte[])message;
//原样输出给客户端
session.write(message);
} @Override
public void sessionIdle(IoSession session, IdleStatus status) throws Exception { super.sessionIdle(session, status);
}
}

4、Mina Server

//这里要开启多个server,只开启一个server的情况需要修改下面的代码
public class MinaService { public boolean startMinaServer(Integer port) {
// 1. 创建IoAcceptor
IoAcceptor acceptor = new NioSocketAcceptor();
// 2. 加入日志记录过滤器,用SL4J库记录信息
acceptor.getFilterChain().addLast("logger", new LoggingFilter());
// 3. 加入编码过滤器,用于解码所有收到的信息,使用 new TextLineCodecFactory() r
// 发送的信息进行编码,返回是MINA自带的,功能有限,只能处理文本戒者String类型。
acceptor.getFilterChain().addLast("socketFilter", new ProtocolCodecFilter(new TcpProtocolCodecFactory()));
// 4. 设置ServerHandler, 自定义的Handler,TimeServerHandler
acceptor.setHandler(new MinaClientHandler());
// 5. 设置空闲时间, 这里的BOTH_IDLE指EADER_IDLE和WRITER_IDLE都为120秒
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 120);
// 6. 绑定监听端口.
try {
acceptor.bind(new InetSocketAddress(port));
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
}

5、使用Telnet进行测试(本Server因为只处理特定协议的byte[]数据,因此不能直接使用telnet测试)

telnet ip 端口

6、特别注意:尽量把日志系统配置好并开启,可以快速定位错误并有助于跟踪服务的运行。

Mina Tcp服务器开发的更多相关文章

  1. 机动车驾驶员计时培训系统符合性检测平台TCP服务器设计和开发

    驾校计时平台的TCP服务器,主要用于接入计时终端,计时终端与计时平台.计时平台与省级监管服务平台.省级监管服务平台与全国驾培平台的卫星定位过程明细数据和学时过程明细数据接口应使用基于JT/T 808标 ...

  2. Mina、Netty、Twisted一起学(一):实现简单的TCP服务器

    MINA.Netty.Twisted为什么放在一起学习?首先,不妨先分别看一下它们官方网站对其的介绍: MINA: Apache MINA is a network application frame ...

  3. 【Andorid开发框架学习】之Mina开发之服务器开发

    下午那篇博客我们讲到了Mina的客户端的开发,如果还有没看过的同学可以看一下,我是传送门.现在,我们来学习一下,Mina的服务器的开发. 一.首先看一下,我的服务器的代码图片:  服务器代码我是在My ...

  4. <摘录>详谈高性能TCP服务器的开发

    对于开发一款高性能服务器程序,广大服务器开发人员在一直为之奋斗和努力.其中一个影响服务器的重要瓶颈就是服务器的网络处理模块.如果一款服务器程序不能及时的处理用户的数据.则服务器的上层业务逻辑再高效也是 ...

  5. 16-ESP8266 SDK开发基础入门篇--TCP 服务器 非RTOS运行版,串口透传(串口回调函数处理版)

    https://www.cnblogs.com/yangfengwu/p/11105466.html 其实官方给的RTOS的版本就是在原先非RTOS版本上增加的 https://www.cnblogs ...

  6. LwIP应用开发笔记之五:LwIP无操作系统TCP服务器

    前面我们实现了UDP服务器及客户端以及基于其上的TFTP应用服务器.接下来我们将实现同样广泛应用的TCP协议各类应用. 1.TCP简述 TCP(Transmission Control Protoco ...

  7. 18-ESP8266 SDK开发基础入门篇--TCP 服务器 RTOS版,串口透传,TCP客户端控制LED

    https://www.cnblogs.com/yangfengwu/p/11112015.html 先规定一下协议 aa 55 02 01 F1 4C 控制LED点亮  F1 4C为CRC高位和低位 ...

  8. 17-ESP8266 SDK开发基础入门篇--TCP服务器 RTOS版,小试牛刀

    https://www.cnblogs.com/yangfengwu/p/11105466.html 现在开始写... lwip即可以用socket 的API  也可以用 netconn  的API实 ...

  9. 基于MINA框架快速开发网络应用程序

    1.MINA框架简介 MINA(Multipurpose Infrastructure for Network Applications)是用于开发高性能和高可用性的网络应用程序的基础框架.通过使用M ...

  10. socket服务器开发中的SO_REUSEADDR选项与让人心烦的TIME_WAIT

    1 发现问题 我在开发一个socket服务器程序并反复调试的时候,发现了一个让人无比心烦的情况:每次kill掉该服务器进程并重新启动的时候,都会出现bind错误:error:98,Address al ...

随机推荐

  1. go基础-依赖管理

    有些不可思议,简洁.优雅的go语言依赖管理如此混乱,发布多年也没有可靠的依赖管理机制,官方先后推出了多种依赖管理机制gopath.vendor.dep等,没有一个顺手,直到在Go 1.11推出go m ...

  2. 从ClickHouse通往MySQL的几条道路

    一.应用背景简介 ClickHouse 是 Yandex(俄罗斯最大的搜索引擎)开源的一个用于实时数据分析的基于列存储的数据库,其处理数据的速度比传统方法快 100-1000 倍.ClickHouse ...

  3. ConcurrentModificationException日志关键字报警引发的思考

    本文将记录和分析日志中的ConcurrentModificationException关键字报警,还有一些我的思考,希望对大家有帮助. 一.背景 近期,在日常的日志关键字报警分析时,发现我负责的一个电 ...

  4. 企业应用开发中.NET EF常用哪种模式?

    前言 本篇文章来源于微信技术群小伙伴的提问,在企业应用开发中.NET ORM EF常用哪种模式进行开发?今天我们一起来了解一下EF开发的三种模式. EF/EF Core介绍 Entity Framew ...

  5. Mybatis-Flex核心功能之@Column

    1.是什么? MyBatis-Flex 提供了 @Column 用来对字段进行更多的配置 public @interface Column { /** * 字段名称 */ String value() ...

  6. visual studio 2013 汇编环境配置

    网上有很多教程,但是第一次运行仍然出现很多问题,后来我发现忽视了几个个重要的点!!!红色字体标注 教程搬自:https://github.com/JunpengCode/Assembly https: ...

  7. 腾讯云服务器安装MySQL5.7基于xshell

    腾讯云服务器安装MySQL5.7基于xshell 下载MySQL57安装包 wget https://dev.mysql.com/get/mysql57-community-release-el7-1 ...

  8. VS2022 安装 .NET Framework 4.0 和 .NET Framework 4.5 的方法

    解决方法 1.下载.NET Framework框架 .NET Framework 4.5.2 .NET Framework 4.5.1 .NET Framework 4.5 .NET Framewor ...

  9. 『Flutter』开发环境搭建

    1.前言 大家好,我是 BNTang,今天给大家介绍一下 Flutter 的开发环境搭建.在之前我已经将 Dart 的基本语法给大家介绍了,所以今天就不再介绍 Dart 的基本语法了,直接进入 Flu ...

  10. Navicat Premium多用户破解方法 12以上版本

    https://www.cnblogs.com/cgqplus/p/15267306.html 本文不提供注册机或者破解工具,本论坛多的是,搜索一下就好了. 本方法适用于多用户环境下使用,比如在服务器 ...