java mina 框架 获取字节_浅谈Java的Mina框架传递对象

article/2025/10/1 16:44:39

接触java的Mina框架已经有很多时间了,在网上也读过了很多的相关文章,发现Mina框架的确是一个值得拿来好好研究的东西,前些日子写了一个山寨QQ项目,其中的通信部分用到了java中自带的InputStream,OutputStream,Writer,Reader等等,感觉其中的很大的一个问题就是难以将事务处理的逻辑层与解析层分离开来,造成整个项目看起来比较臃肿,繁琐,不够模块化,接触Mina后发现mina在这方面做的很是恰到好处。

看到文章标题,你或许会有一些疑惑:

1、Mina框架传递对象是怎么回事

2、Mina传递对象可以用来做什么

3、Mina传递对象是怎么进行的

4、Mina传递对象过程中会遇到什么问题呢

在用原来的java的InputStream,OutputStream,Writer,Reader等进行通信的时候我们会将信息编码转化成字节流等进行信息传递,InputStream,OutputStream是基于字节流的,而Writer,Reader是基于字符的,我们都知道进行通信的服务器和客户端是事先必须定好通信协议,如果我们将你好吗?定义为是一条消息,视频定义为一条视频请求,如果客户端将这条消息和请求发送给了服务器,服务器要想得到消息和请求的真正内容(在这里分别是“你好吗?”和“视频”)并进行处理和应答就必须进行信息的解析,就要一条一条的进行判断:1、如果是信息是……格式的就将其看做是一条消息;2、如果是……格式的就将其看作是一条请求;3、如果是其他形式就将其视为无效信息,不予处理。当然这不失为一种办法可以进行信息的提取,但是我们会发现在这个过程中信息的发送、接受、解析、处理、应答等都是一条一条的,很是零散,比较难以统一,没有实现消息定义和解析处理过程的分离,这样写好了一个程序,如果日后想要进行改正其中的一条信息格式,就要在整个项目中Ctrl+F了,比较繁琐,还容易出错。

这是我们会自然的想到要用一种东西将各个格式的信息进行分类统一起来并方便进行一些必要的信息处理,为符合这些特点,我们会想到类这个东东恰恰满足了这些性质,我们可以将信息的格式中的内容定义为类的属性,而对这些属性的处理就可以用类中的方法来予以解决,这样就对信息进行了很好的包装。

这种思想有了,那就是在通信的时候直接进行形式上的对象传递(实际上在通信的时候都是最终以字节流的方式进行传递的),那么我们就要找一种工具进行这种形式的信息传递,对了,这种工具就是Mina框架,我们只看他其中的一个方法

public void messageReceived(IoSession session, Object message),这是进行消息接收是能够被 触发的一个方法,参数session代表当前的会话对象,参数message代表接收的到的信息,这时您会发现message的类型是Object型,而类 Object 是类层次结构的根类,当然可以用对象型的作为message啦!前面提到通信的时候都是最终以字节流的方式进行传递的,这样就要进行:对象(客户端)->字节流(客户端)->发送->接收->字节流(服务器)->对象(服务器)的过程,呵呵不用担心,这些繁琐的过程,Mina都提供了很好的底层默认实现所以你只需稍稍敲点代码就行了。

光说不练还是不行,先上一个程序实例:

服务器端(1):

Java代码

packageMina.server;

importjava.io.IOException;

importjava.net.InetSocketAddress;

importorg.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;

importorg.apache.mina.filter.codec.ProtocolCodecFilter;

importorg.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;

importorg.apache.mina.transport.socket.SocketAcceptor;

importorg.apache.mina.transport.socket.nio.NioSocketAcceptor;

publicclassMainServer {

privatestaticMainServer mainServer =null;

privateSocketAcceptor acceptor =newNioSocketAcceptor();

privateDefaultIoFilterChainBuilder chain = acceptor.getFilterChain();

privateintbindPort =8888;

publicstaticMainServer getInstances() {

if(null== mainServer) {

mainServer =newMainServer();

}

returnmainServer;

}

privateMainServer() {

chain.addLast("myChin",newProtocolCodecFilter(

newObjectSerializationCodecFactory()));

acceptor.setHandler(ServerHandler.getInstances());

try{

acceptor.bind(newInetSocketAddress(bindPort));

}catch(IOException e) {

e.printStackTrace();

}

}

publicstaticvoidmain(String[] args)throwsException {

MainServer.getInstances();

}

}

服务器端(2):

Java代码

packageMina.server;

importorg.apache.mina.core.filterchain.IoFilterAdapter;

importorg.apache.mina.core.service.IoHandler;

importorg.apache.mina.core.session.IdleStatus;

importorg.apache.mina.core.session.IoSession;

importMina.Object.UserInfo;

publicclassServerHandlerextendsIoFilterAdapterimplementsIoHandler {

privatestaticServerHandler samplMinaServerHandler =null;

publicstaticServerHandler getInstances() {

if(null== samplMinaServerHandler) {

samplMinaServerHandler =newServerHandler();

}

returnsamplMinaServerHandler;

}

privateServerHandler() {

}

// 当连接后打开时触发此方法,一般此方法与 sessionCreated 会被同时触发

publicvoidsessionOpened(IoSession session)throwsException {

}

publicvoidsessionClosed(IoSession session) {

}

publicvoidmessageReceived(IoSession session, Object message)

throwsException {

if(messageinstanceofUserInfo) {

UserInfo text = (UserInfo) message;

System.out.println("服务器接收到从客户端的姓名:"+text.getName());

System.out.println("服务器接收到从客户端的QQ:"+text.getQQNum());

}

}

publicvoidexceptionCaught(IoSession arg0, Throwable arg1)

throwsException {

}

// 当消息传送到客户端后触发

publicvoidmessageSent(IoSession arg0, Object arg1)throwsException {

}

// 当一个新客户端连接后触发此方法.

publicvoidsessionCreated(IoSession arg0)throwsException {

}

// 当连接空闲时触发此方法.

publicvoidsessionIdle(IoSession arg0, IdleStatus arg1)throwsException {

}

}

客户端(1):

Java代码

packageMina.client;

importjava.net.InetSocketAddress;

importorg.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;

importorg.apache.mina.core.future.ConnectFuture;

importorg.apache.mina.filter.codec.ProtocolCodecFilter;

importorg.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;

importorg.apache.mina.transport.socket.nio.NioSocketConnector;

publicclassMainClient {

privatestaticMainClient mainClient =null;

NioSocketConnector connector =newNioSocketConnector();

DefaultIoFilterChainBuilder chain = connector.getFilterChain();

publicstaticMainClient getInstances() {

if(null== mainClient) {

mainClient =newMainClient();

}

returnmainClient;

}

privateMainClient() {

chain.addLast("myChin",newProtocolCodecFilter(

newObjectSerializationCodecFactory()));

connector.setHandler(ClientHandler.getInstances());

connector.setConnectTimeout(30);

ConnectFuture cf = connector.connect(newInetSocketAddress("localhost",

8888));

}

publicstaticvoidmain(String args[]) {

MainClient.getInstances();

}

}

客户端(2):

Java代码

0950260.gif

packageMina.client;

importorg.apache.mina.core.service.IoHandlerAdapter;

importorg.apache.mina.core.session.IoSession;

importMina.Object.UserInfo;

publicclassClientHandlerextendsIoHandlerAdapter {

privatestaticClientHandler samplMinaClientHandler =null;

publicstaticClientHandler getInstances() {

if(null== samplMinaClientHandler) {

samplMinaClientHandler =newClientHandler();

}

returnsamplMinaClientHandler;

}

privateClientHandler() {

}

publicvoidsessionOpened(IoSession session)throwsException {

session.write("客户端与服务器的会话打开了……");

UserInfo text=newUserInfo();

text.setName("梅竹寒香");

text.setQQNum("972341215");

session.write(text);

}

publicvoidsessionClosed(IoSession session) {

}

publicvoidmessageReceived(IoSession session, Object message)

throwsException {

}

publicvoidmessageSent(IoSession arg0, Object arg1)throwsException {

System.out.println("客户端已经向服务器发送了:"+(String)arg1);

}

}

公共类:

Java代码

0950260.gif

packageMina.Object;

publicclassUserInfoimplementsjava.io.Serializable{

privateString name;

privateString QQNum;

publicString getName() {

returnname;

}

publicvoidsetName(String name) {

this.name = name;

}

publicString getQQNum() {

returnQQNum;

}

publicvoidsetQQNum(String qQNum) {

QQNum = qQNum;

}

}

如下建包即可:

5ce698984d2637e0e8e82b38f622e71c.png

以上就是对象的收发的简单示例,如果报错,或许会是一下原因:1、包的引进是否妥当 2、是否引入了mina的第三方包(网上有了很多的相关文章,在此就不在赘述了)

通过程序您会看到对象已经成功传递并进行了相关属性的输出,对于这个简单的程序我稍做些相关说明:

1、进行传递的对象所实例化的类要实现java.io.Serializable序列化接口

2、您会发现实例中的类尤其是相关的IoHandlerAdapter继承类都采用了单实例模式,为什么这样做呢,原因很简单,那就是要在整个通信过程中做到对象session的等实例的单一防止发生“所托非人”的现象

3、服务器接收到message在进行类判断时用了instanceof关键字

如果你看到上面的实例就觉得对象传递的学习已经成功了,那就错了,细心的博友看到这个包结构:

5ce698984d2637e0e8e82b38f622e71c.png

是不是有点问题呢。

例如客户端传了一个userinfo对象到服务器,在服务器端判断如果是userinfo对象后就打印出相关信息,我看源码文档其中有这样的建包方式

5ce698984d2637e0e8e82b38f622e71c.png

其中服务器和客户端共用了中间的Mina.Object包,这样在收到对象后就能通过instanceof关键字判断是不是useinfo对象,我看了一下,这个方法是可行的,现在的问题是,我们如果编写通讯软件的时候,肯定是服务器和客户端是要分开的,所以那个Mina.Object包是不能共享的,所以问题来了(1)、如果将userinfo放到客户端中,那么该怎么用instanceof进行判断是不是userinfo呢(这时你已经不能再引入服务器中的userinfo了)(2)、如果在客户端和服务器中都编写一个类定义一样的userinfo,可是他们这两个类是分属不同的包,所以是两个不同的类了,这样在用instanceof进行判断的时候也是行不通的;那么我们该用什么方法来进行判断接收到的类是不是userinfo对象呢?

这个问题把我纠结了很久,在网上面搜了好久也没有解决,最后想了想那个(2)或许可以改动改动就可以解决,问题的关键在于两个UserInfo分属于两个不同的包,如果可以将包名一致就好了,但是在一个工程里面不能同时建立两个命名一样的包,这样你就会发现何不建立两个工程呢一个是服务器,一个是客户端,这样都可以分别建立名字都是Object的包,这样可不可行呢,经过试验果然可以,这样就就解决了上面的问题工程图如下

853c2ce841ea1d7771a8119c36ab2c30.png

好啦,有了这个工具,您会有什么想法呢?对象传递还可以做什么?那就是可以用它来进行图片,文件的传递啦,这个只是个小小的提示具体怎么实现,就要看各位博友怎么发挥啦!呵呵


http://chatgpt.dhexx.cn/article/emYQYREc.shtml

相关文章

Java网络编程之MINA框架(1)

1、MINA: 一个简洁易用的基于TCP/IP通信的JAVA框架 2、下载地址: http://mina.apache.org/downloads-mina_2_0.html 3、至少需要: (在下载的文件中找以下两个jar包导入工程中) mina-core-2.0.21.jar、slf4j-api-1.7.26.jar 4、开发一个Mina应…

浅谈Mina框架

一、简介 Apache Mina Server 是一个网络通信应用框架,也就是说, 也可以提供JAVA对象的序列化服务、虚拟机管道通信服务等),Mina可以帮助我们快速开发高性能、高扩展性的网络通信应用,Mina提供了事件驱动、异步&#…

java mina框架实例_Apache Mina框架实践

1.为什么要用Apache Mina框架 ApacheMina Server 是一个网络通信应用框架,Mina 可以帮助我们快速开发高性能、高扩展性的网络通信应用,Mina 提供了事件驱动、异步(Mina 的异步IO 默认使用的是JAVANIO 作为底层支持)操作的编程模型。 2.ApacheMina框架使用 Mina的执行…

mina框架详解-小白收藏

目录 mina框架详解 1 简介 1.1 工作流程 1.2 服务端流程 2 简单的TCPServer 3 简单的TCPClient 4 介绍Mina的TCP的主要接口 5 日志配置 6 过滤器 7 协议编解码器 8 线程模型配置 mina框架详解 1 简介 Apache Mina Server 是一个网络通信应用框架,也就是…

Mina网络通信框架

认识 Mina Apache Mina Server 是一个网络通信应用框架,与 Netty 出自同一作者,Netty 借鉴了部分 Mina 的设计思路。 Mina 主要是对基于 TCP/IP、UDP/IP 协议栈的通信框架,Mina 可以帮助我们快速开发高性能、高扩展性的网络通信应用&#x…

MINA框架

MINA框架 一、小程序MINA框架分为三个部分: 有 View(视图层)、App Service(逻辑层)和 Natice(系统层)。 1、View(视图层) 视图层包含了小程序多个页面、每个页面都有WXML文件和 WXSS文件,是搭建页面视图的结构和展现样式。 2、App Service(逻辑层) …

图文详解mina框架

Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP、UDP/IP协议栈的通信框架(当然,也可以提供JAVA 对象的序列化服务、虚拟机管道通信服务等),Mina 可以帮助我们快速开发高性能、高扩展性的网络通信应用,Mina 提供了事件驱动、异步(Mina 的异步…

要点初见:用Python进行微观交通模型仿真——基于SUMO的伯克利开源项目Flow Project初探与拓展

后续拓展:要点初见:安装教程与二度拓展——基于SUMO的Flow Project(附代码链接) 通俗来讲,微观交通模型仿真就是从车辆个体的视角(看动画)进行交通流仿真,对车辆个体随时间、空间的…

爬取豆瓣电影TOP100

爬虫 首先我们在网站中打开我们要爬的网站 “http://maoyan.com/board/4” 这就是豆瓣高分电影前100的榜单. 然后我们点击f12,再刷新一次,就可以看到网页的基本信息了。 这时候我们来看一下第一部‘我不是药神中的代码信息。’ 一个dd节点为一个电影的…

2020 年软件设计师考试上午真题

2020 年软件设计师考试上午真题答案解析 1、在程序执行过程中,高速缓存(Cache) 与主存间的地址映射由(D )。 A、操作系统进行管理 B、存储管理软件进行管理 C、程序员自行安排 D、硬件自动完成 解:CACHE与主存地址映射由硬件完成…

基于LLVM的编译原理简明教程 (1) - 写编译器越来越容易了

基于LLVM的编译原理简明教程 (1) - 写编译器越来越容易了 进入21世纪,新的编程语言如雨后春笋一样不停地冒出来。需求当然是重要的驱动力量,但是在其中起了重要作用的就是工具链的改善。 2000年,UIUC的Chris Lattner主持开发了一套称为LLVM…

基于LLVM的编译原理简明教程: 写一个自己的编译器​

LLVM简介 进入21世纪,新的编程语言如雨后春笋一样不停地冒出来。需求当然是重要的驱动力量,但是在其中起了重要作用的就是工具链的改善。 2000年,UIUC的Chris Lattner主持开发了一套称为LLVM(Low Level Virtual Machine)的编译器工具库套件。…

【极富参考价值!】第1章 ClickHouse 简介《ClickHouse 企业级大数据分析引擎实战》...

《ClickHouse 企业级大数据分析引擎实战》全书目录 目录 第1章 ClickHouse 简介 第2章 MergeTree 表存储引擎 第3章 ClickHouse SQL 执行原理 第4章 分布式的 ClickHouse:集群、分片、副本 第5章 项目实战:Spring Boot 集成 ClickHouse 第6章 ClickHouse 函数 第7章 集成外部…

32.3-5带有通配符的匹配(自动机)

功能 这个程序可以判断一个带有通配符*的模式串是否在文本串中存在,没有记录位置信息,当然,想记录也是可以的 样例输入: abccbacbababc ab*bab*c 样例输出: 1 思路 对于样例输入,有限自动机如图所示: 我们把每个通配符隔开的字串看做独立的,在其上运行KMP算法的comput_s…

自己动手写编译器:代码实现正则表达式到NFA状态机

在编译器开发中有两个非常重要的工具名为lex和yacc,他们是编译器的生成器。本质上我们不需要一行行去完成编译器的代码,只需要借助这两个工具,同时制定好词法解析和语法解析的规则后,这两个工具就会自动帮我们把代码生成&#xff…

mac搭建网站服务器,Mac上搭建Web服务器--Apache

局域网搭建 Web 服务器测试环境,因为Mac OS X 自带了 Apache 和 PHP 环境,我们只需要简单的启动它就行了。 1.命令:sudo apachectl start Apache服务器默认的web根目录在:/Library/WebServer/Documents Apache的配置文件在:/etc/apache2 相关命令: 停止 Apache:sudo apac…

aText for Mac(打字加速器)

aText作为一款文字效率的工具,对于文字工作者来说这款软件的目的是为了减少你在文字输入的过程当中的重复性,这款试用版本能够让你体验到一些较为基础的功能。 aText下载安装教程 镜像包下载完成后打开,双击.pkg按照安装引导器进行安装即可&a…

共享文件夹无法打开——服务器存储空间不足,无法处理此命令

原文地址为: 共享文件夹无法打开——服务器存储空间不足,无法处理此命令 共享某个文件夹后在网上邻居打开它,提示:“服务器存储空间不足,无法处理此命令”,如下图: 查看系统日志显示&#xff1…

彻底解决win10 docker desktop镜像过大导致“C盘存储空间不足”的问题。

彻底解决win10 docker desktop镜像过大导致“C盘存储空间不足”的问题。 win10安装docker只需要双击安装包,真正实现了傻瓜式安装,这一点真的十分方便!不过用了义端时间docker后,突然有一天我注意到C盘原本充裕的空间容量&#x…

mysql数据库空间不足_mysql空间不足怎么解决?

磁盘空间不足,使用du命令察看 du -h --max-depth1 当前目录下占空间比较大的是104个mysql-bin.00000X 和ibdata1。 mysql数据目录下有大量的mysql-bin.00000X文件,这些文件是做什么的呢? 这是数据库的操作日志,例如UPDATE一个表&a…