① 安卓会不会用到apache mina
最近在做一个项目的android的网络模块,发送认证消息及请求信息至服务器,通过认证后,服务器返回我所需的数据流,选择Apache mina作为框架,在IOFilter层,我设置过滤器为
IoConnector connector=new NioSocketConnector();
connector.getFilterChain().addLast(
"myCodec",
new ProtocolCodecFilter(new TextLineCodecFactory(Charset
.forName("GB2312"))));
联网认证成功后,返回的数据流不是字符串类型,使用该过滤器报异常了:org.apache.mina.filter.codec.ProtocolDecoderException: java.nio.charset.MalformedInputException: Input length = 1 (Hexmp:
大致是字符串乱码问题,无法解析,网上查了一些资料,没有解决方案。
我想应该是过滤器设置的问题,因为返回的数据流本来就不是字符串类型,经该过滤器处理,自然会出错。我觉得应该有两种方法来解决这个问题:
(1)不使用mina自带的过滤器,自己写一个过滤器;发现这样可能比较麻烦,显得比较复杂,加上我也是新手一枚,难度有点大,放弃了...
(2)不使用mina的过滤器,mina框架为3层,过滤器设置处于第二层,我在此处不设置过滤器,直接将我要发送到服务器的内容转换为byte型数组写入IoBuffer中,将IoBuffer发送到服务器,代码如下:
connector = new NioSocketConnector(); connector.setConnectTimeoutMillis(3000);
connector.setHandler(new ClientHandler(MinaTest4AndroidActivity.this, mFd));
future = connector.connect(new InetSocketAddress(host, port));// 创建连接 future.awaitUninterruptibly();// 等待连接创建完成
String info ="这里是你需要发送到服务器的数据.......";
byte bt[]=info.getBytes();//转换为字节型数组 IoBuffer info_buffer=IoBuffer.allocate(bt.length);
info_buffer.put(bt,0,bt.length);//写入buffer中
info_buffer.flip();
session = future.getSession(); session.write(info_buffer);// 不使用过滤器,直接发送字节流
这样不经过过滤器,便不会报该异常,当然,没有了过滤器,在
@Override public void messageReceived(IoSession session, Object message)
throws Exception {
IoBuffer buffer = (IoBuffer) message;
}该函数中接收到得为IoBuffer型,然后根据需要将它转化为需要的数据类型。
这样,不会再报异常,在IoHandler中根据服务器返回的数据,再做相应的业务上的处理.......
② mina的过滤器别名能随便取么
底层通信比较多的 一般的消息系统中间件 都可以用的 还有很多分布式的也会用到通信的 凡是用到通信的 都可以用mina的
③ androidpn tomcat版有什么优点
在Androidpn的底层主要采用的两大框架mina和openfire两大框架,其中mina主要为底层数据传输的Socket框架。下面简单的介绍一下Socket框架
Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP、UDP/IP协议栈的通信框架(也可以提供JAVA 对象的序列化服务、虚拟机管道通信服务等),Mina 同时提供了网络通信的Server 端、Client 端的封装,无论是哪端,Mina 在整个网通通信结构中都处于如下的位置:
1.spring初始化并启动过程,调用NioSocketAcceptor。
2.NioSocketAcceptor开始执行调用IoProcessor.
3.IoProcessor开始调用FilterChain。FilterChain调用相关的IoFilter的。其中ProtocolCodecFilter的过滤器调用了org.androidpn.server.xmpp.codec.XmppCodecFactory进行编码。
4.XmppIoHandler实现自IoHanlder并调用通过openfire 的XMLLightweightParser解析相关的业务逻辑。
5.根据解析的信息调用xmpp并处理相关信息。
AndroidPN(Android Push Notification) 是一个基于XMPP协议的Java开源推送通知实现,它包含了完整的客户端和服务端。
AndroidPN基于Openfire下的一些开源项目构建。
AndroidPN服务器包含两个部分,
一个是侦听在5222端口上的XMPP服务,负责与客户端的XMPPConnection类进行通信,作用是用户注册和身份认证,并发送推送通知消息。
另外一部分是Web服务器,采用一个轻量级的HTTP服务器,负责接收用户的Web请求。
最上层包含四个组成部分,分别是SessionManager,Auth Manager,PresenceManager以及Notification Manager。
SessionManager负责管理客户端与服务器之间的会话。
Auth Manager负责客户端用户认证管理。
Presence Manager负责管理客户端用户的登录状态。
NotificationManager负责实现服务器向客户端推送消息功能。
IQHandler消息处理器的类:
IQHandler:消息处理器抽象类。
IQAuthHandler:权限协议的消息处理类,消息的类型为:jabber:iq:auth
IQRegisterHandler:用户注册的消息处理类,消息类型为: jabber:iq:register
IQRosterHandler:用户消息交互类,消息类型为:jabber:iq:roster
PresenceUpdateHandler:用户状态展现变化处理类。内部调用,不具有类型。
④ java mina接收与发送字节数组(byte[])
要自己根据发送的数据包格式写一个过滤器 ,或者将发送的数据包封装成对象再发送。
⑤ mina tcp server怎么发命令
Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP、UDP/IP协议栈的通信框架(当然,也可以提供JAVA 对象的序列化服务、虚拟机管道通信服务等),Mina 可以帮助我们快速开发高性能、高扩展性的网络通信应用,Mina 提供了事件驱动、异步(Mina 的异步IO 默认使用的是JAVA NIO 作为底层支持)操作的编程模型。Mina 主要有1.x 和2.x 两个分支,这里我们讲解最新版本2.0,如果你使用的是Mina 1.x,那么可能会有一些功能并不适用。学习本文档,需要你已掌握JAVA IO、JAVA NIO、JAVASocket、JAVA 线程及并发库(java.util.concurrent.*)的知识。Mina 同时提供了网络通信的Server 端、Client 端的封装,无论是哪端,Mina 在整个网通通信结构中都处于如下的位置:可见Mina 的API 将真正的网络通信与我们的应用程序隔离开来,你只需要关心你要发送、接收的数据以及你的业务逻辑即可。同样的,无论是哪端,Mina 的执行流程如下所示:
(1.) IoService:这个接口在一个线程上负责套接字的建立,拥有自己的Selector,监听是否有连接被建立。
(2.) IoProcessor:这个接口在另一个线程上,负责检查是否有数据在通道上读写,也就是说它也拥有自己的Selector,这是与我们使用JAVA NIO 编码时的一个不同之处,通常在JAVA NIO 编码中,我们都是使用一个Selector,也就是不区分IoService与IoProcessor 两个功能接口。另外,IoProcessor 负责调用注册在IoService 上的过滤器,并在过滤器链之后调用IoHandler。
(3.) IoFilter:这个接口定义一组拦截器,这些拦截器可以包括日志输出、黑名单过滤、数据的编码(write 方向)与解码(read 方向)等功能,其中数据的encode 与decode是最为重要的、也是你在使用Mina 时最主要关注的地方。
(4.) IoHandler:这个接口负责编写业务逻辑,也就是接收、发送数据的地方。
1. 简单的TCPServer:
(1.) 第一步:编写IoService
按照上面的执行流程,我们首先需要编写IoService,IoService 本身既是服务端,又是客户端,我们这里编写服务端,所以使用IoAcceptor 实现,由于IoAcceptor 是与协议无关的,因为我们要编写TCPServer,所以我们使用IoAcceptor 的实现NioSocketAcceptor,实际上底层就是调用java.nio.channels.ServerSocketChannel 类。当然,如果你使用了Apache 的APR 库,那么你可以选择使AprSocketAcceptor 作为TCPServer 的实现,据传说Apache APR库的性能比JVM 自带的本地库高出很多。那么IoProcessor 是由指定的IoService 内部创建并调用的,我们并不需要关心。
这段代码我们初始化了服务端的TCP/IP 的基于NIO 的套接字,然后调用IoSessionConfig设置读取数据的缓冲区大小、读写通道均在10 秒内无任何操作就进入空闲状态。
(2.) 第二步:编写过滤器
这里我们处理最简单的字符串传输,Mina 已经为我们提供了TextLineCodecFactory 编解码器工厂来对字符串进行编解码处理。
这段代码要在acceptor.bind()方法之前执行,因为绑定套接字之后就不能再做这些准备工作了。这里先不用清楚编解码器是如何工作的,这个是后面重点说明的内容,这里你只需要清楚,我们传输的以换行符为标识的数据,所以使用了Mina 自带的换行符编解码器工厂。
(3.) 第三步:编写IoHandler
这里我们只是简单的打印Client 传说过来的数据。
然后我们把这个IoHandler 注册到IoService:
当然这段代码也要在acceptor.bind()方法之前执行。然后我们运行MyServer 中的main 方法,你可以看到控制台一直处于阻塞状态,此时,我们用telnet 127.0.0.1 9123 访问,然后输入一些内容,当按下回车键,你会发现数据在Server 端被输出,但要注意不要输入中文,因为Windows 的命令行窗口不会对传输的数据进行UTF-8 编码。当输入quit 结尾的字符串时,连接被断开。这里注意你如果使用的操作系统,或者使用的Telnet 软件的换行符是什么,如果不清楚,可以删掉第二步中的两个红色的参数,使用TextLineCodec 内部的自动识别机制。
⑥ org.apache.mina.core.buffer.iobuffer在哪个jar包
mina 心跳机制 ieRequest isResponse到底什么时候调用 上下文设置: 服务器端基于Mina开发,心跳包25秒发一次0D+0A,客户端收到后,回0D-0A 因为客户端设置了60秒一次心跳包,所以心跳包有服务器端先发起。 客户端心跳过滤器代码:
⑦ apache mina 或者 netty ssl 通道加密,如何实现部分加密。
影响只是一点点,不是很多。就在和服务器对接握手那一刻,成功后就和平时的一样呢。建议还是整站加密。因为你只加密一部分。黑客可以通过其中的漏洞去入侵——沃通CA机构做数字认证证书领域的领跑者,buy.wosign.com
⑧ java 采用mina进行网络连接,怎样在客户端绑定本地的ip和port,下面的程序只指定了服务器端
ConnectFuture future = connector.connect(new InetSocketAddress(
host, port));// 创建连接
future.awaitUninterruptibly();// 等待连接创建完成
⑨ MINA框架中文件传输
session.write()函数,写入的是一个object对象,不能传输byte数组,所以你的传输过去的byte数组就不正确了 。。你应该用了mina提供的过滤器,所以客户端和服务器端才可以通讯,如果你不用过滤器,你用session.write()函数将byte数组发送给服务器,服务器是接受不到消息的,也就是在serverHandler类中不会触发messageReceive函数。。mian是一个事件驱动模型的框架 。 。如果不用过滤器的话只能传输bytebuffer对象。想解决文件传输,你可以在客户端用输入流InputStream对象读取文件放入byte数组中,然后将byte数组转化成bytebuffer对象,注意这个bytebuffer对象应该是apache提供的 。然后在服务器端用bytebuffer对象接受后再转换成byte数组,这样文件就可以传输了 。 我也是刚刚研究mina。这个方法只是下下策。我想mina框架中有一个fillter可以传输文件的 。 你好好看看mina api吧。对了我研究的是mina1.7版本的。。。希望我的回答对你有所帮助。
⑩ mina 心跳机制 ieRequest isResponse毕竟什么时候调用
mina 心跳机制 ieRequest isResponse到底什么时候调用
上下文设置:
服务器端基于Mina开发,心跳包25秒发一次0D+0A,客户端收到后,回0D-0A
因为客户端设置了60秒一次心跳包,所以心跳包有服务器端先发起。
客户端心跳过滤器代码:(服务器端代码就不贴了,差不多的)
package com.mina.client;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.keepalive.KeepAliveFilter;
import org.apache.mina.filter.keepalive.KeepAliveMessageFactory;
import org.apache.mina.filter.keepalive.;
public class MyKeepAliveFilter extends KeepAliveFilter {
public MyKeepAliveFilter() {
super(new KeepAliveMessageFactoryImpl(), IdleStatus.BOTH_IDLE, new ExceptionHandler(), 60, 70);
this.setForwardEvent(false); //此消息不会继续传递,不会被业务层看见
}
}
class ExceptionHandler implements {
public void keepAliveRequestTimedOut(KeepAliveFilter filter, IoSession session) throws Exception {
System.out.println("心跳超时");
session.close(true);
}
}
class KeepAliveMessageFactoryImpl implements KeepAliveMessageFactory {
private static final byte int_req = '+'; // 2B
private static final byte int_rep = '-'; // 2D
private static final IoBuffer KAMSG_REQ = IoBuffer.wrap(new byte[]{0x0D, '+', 0x0A});
private static final IoBuffer KAMSG_REP = IoBuffer.wrap(new byte[]{0x0D, '-', 0x0A});
/**
* 此方法为发心跳包,发+
*/
@Override
public Object getRequest(IoSession arg0) {
System.out.println();
System.out.println(new SimpleDateFormat("yyyyMMdd-HH:mm:ss-SSS").format(new Date()) + " 发心跳包+:" + KAMSG_REQ.plicate());
return KAMSG_REQ.plicate();
}
/**
* 收到对方的心跳包后,此方法回心跳包,回-
*/
@Override
public Object getResponse(IoSession arg0, Object arg1) {
System.out.println();
System.out.println(new SimpleDateFormat("yyyyMMdd-HH:mm:ss-SSS").format(new Date()) + " 回心跳包-:" + KAMSG_REP.plicate());
return KAMSG_REP.plicate();
}
/**
* 是否是心跳请求包,不管是对方的还是自己的
*/
@Override
public boolean isRequest(IoSession session, Object message) {
if(!(message instanceof IoBuffer)) {
return false;
}
IoBuffer realMessage = (IoBuffer)message;
System.out.println();
if(realMessage.limit() != 3) {
System.out.println(new SimpleDateFormat("yyyyMMdd-HH:mm:ss-SSS").format(new Date()) + " isRequest limit不等于3,RETURN FALSE: message长度:" + realMessage.limit() + " : " + realMessage);
return false;
} else {
System.out.println(new SimpleDateFormat("yyyyMMdd-HH:mm:ss-SSS").format(new Date()) + " isRequest limit等于3, message长度:" + realMessage.limit() + " : " + realMessage);
}
if (realMessage.remaining() != 3) {
return false;
}
byte[] b = new byte[3];
realMessage.get(b);
boolean result = (b[1] == int_req);
System.out.println(new SimpleDateFormat("yyyyMMdd-HH:mm:ss-SSS").format(new Date()) + " isRequest 判断是否为+:" + result);
realMessage.rewind(); // 把pos重新设为0
return result;
}
/**
* 判断是否是心跳响应包,不管是对方的,还是自己的
*/
@Override
public boolean isResponse(IoSession session, Object message) {
if(!(message instanceof IoBuffer)) {
return false;
}
IoBuffer realMessage = (IoBuffer)message;
System.out.println();
if(realMessage.limit() != 3) {
System.out.println(new SimpleDateFormat("yyyyMMdd-HH:mm:ss-SSS").format(new Date()) + " isResponse limit不等于3,RETURN FALSE: message长度:" + realMessage.limit() + " : " + realMessage);
return false;
} else {
System.out.println(new SimpleDateFormat("yyyyMMdd-HH:mm:ss-SSS").format(new Date()) + " isResponse limit等于3, message长度:" + realMessage.limit() + " : " + realMessage);
}
if (realMessage.remaining() != 3) {
return false;
}
byte[] b = new byte[3];
realMessage.get(b);
boolean result = (b[1] == int_rep);
System.out.println(new SimpleDateFormat("yyyyMMdd-HH:mm:ss-SSS").format(new Date()) + " isResponse 判断是否为-:" + result);
realMessage.rewind(); // 把pos重新设为0
return result;
}
}
输出的日志:
20141113-15:49:00-778 isRequest limit等于3, message长度:3 : HeapBuffer[pos=0 lim=3 cap=2048: 0D 2B 0A]
20141113-15:49:00-779 isRequest 判断是否为+:true
20141113-15:49:00-779 回心跳包-:HeapBuffer[pos=0 lim=3 cap=3: 0D 2D 0A]
20141113-15:49:00-780 isResponse limit等于3, message长度:3 : HeapBuffer[pos=0 lim=3 cap=2048: 0D 2B 0A]
20141113-15:49:00-780 isResponse 判断是否为-:false
20141113-15:49:00-781 isRequest limit等于3, message长度:3 : HeapBuffer[pos=0 lim=3 cap=2048: 0D 2B 0A]
20141113-15:49:00-781 isRequest 判断是否为+:true
20141113-15:49:00-782 isRequest limit等于3, message长度:3 : HeapBuffer[pos=0 lim=3 cap=3: 0D 2D 0A]
20141113-15:49:00-783 isRequest 判断是否为+:false
20141113-15:49:00-783 isResponse limit等于3, message长度:3 : HeapBuffer[pos=0 lim=3 cap=3: 0D 2D 0A]
20141113-15:49:00-783 isResponse 判断是否为-:true
20141113-15:49:25-794 isRequest limit等于3, message长度:3 : HeapBuffer[pos=0 lim=3 cap=1024: 0D 2B 0A]
20141113-15:49:25-795 isRequest 判断是否为+:true
20141113-15:49:25-795 回心跳包-:HeapBuffer[pos=0 lim=3 cap=3: 0D 2D 0A]
20141113-15:49:25-796 isResponse limit等于3, message长度:3 : HeapBuffer[pos=0 lim=3 cap=1024: 0D 2B 0A]
20141113-15:49:25-796 isResponse 判断是否为-:false
20141113-15:49:25-797 isRequest limit等于3, message长度:3 : HeapBuffer[pos=0 lim=3 cap=1024: 0D 2B 0A]
20141113-15:49:25-797 isRequest 判断是否为+:true
20141113-15:49:25-798 isRequest limit等于3, message长度:3 : HeapBuffer[pos=0 lim=3 cap=3: 0D 2D 0A]
20141113-15:49:25-798 isRequest 判断是否为+:false
20141113-15:49:25-799 isResponse limit等于3, message长度:3 : HeapBuffer[pos=0 lim=3 cap=3: 0D 2D 0A]
20141113-15:49:25-799 isResponse 判断是否为-:true
有此得出
以上可得出:
对方是25秒一次心跳包,发+
如果对方先发心跳包,我方回心跳-后,如果心跳一直维持,就不会再主动发出+,除非超过设定的60秒的时候。
本地收到消息后
1、走isRequest,发现传递进来的数据为+,则return true,getResponse()回-
2、走isResponse,发现传递进来的数据为+,则return false
3、走isRequest,发现传递进来的数据为+,则return true,但没有回-
4、走isRequest,发现传递进来的数据为-,则return faslse
5、走isResponse,发现传递进来的数据位-,则 return true,但没有回+
如果本地先发心跳包
发+
isRequest 传进来+,对方收到+后,回-
isRequest 传进来-
isResopnse 传进来-
isResponse 传进来-
isResponse 传进来-