Android集成Mina NIO Socket
Mina简介
Apache MINA(Multipurpose Infrastructure 多功能框架 for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用程序提供了非常便利的框架。当前发行的 MINA 版本支持基于 Java NIO 技术的 TCP/UDP 应用程序开发、串口通讯程序,MINA 所支持的功能也在进一步的扩展中。Apache官方网站:http://mina.apache.orgAndroid用jar包等资源 http://pan.baidu.com/s/1i3sY1N3
配置jar包
准备
- 服务器端一共要用到四个jar包,包括一个日志包,它们分别为 mina-core-2.0.7.jar , slf4j-log4j12-1.7.6.jar , slf4j-api-1.7.6.jar , log4j-1.2.17.jar。将他们放在lib中,并加载进去。
- 如果要使用log4j.jar包,则要在项目的src目录下新建一个log4j.properties,内容详见附件。
- Android客户端要加入的jar包:mina-core-2.0.7.jar 和 slf4j-android-1.6.1-RC1.jar。Android自带Log,所以就不使用Mina的日志包了。
![]()
不知道你们注意到了没,客户端的代码与服务器端的极其相似,不同的是服务器是创建NioSocketAcceptor对象,而客户端是创建NioSocketConnect对象。当然同样需要添加编码解码过滤器和业务逻辑过滤器。
Mina的更多功能
- (1)拿到所有客户端Session
Collection<IoSession> sessions = session.getService().getManagedSessions().values();- (2)自定义编码解码器,可以对消息进行预处理。要继承ProtocolEncoder和ProtocolDecode类。
- (3)数据对象的传递
通讯过程
![]()
![]()
![]()
问题: 服务端能收到也能发出消息,但客户端没有任何日志
服务器代码
public class Demo {//日志类的实现private static Logger logger = Logger.getLogger(Demo.class);//端口号,要求客户端与服务器端一致private static int PORT = 4445;public static void main(String[] args) {try {//创建一个【非阻塞】的server端的SocketIoAcceptor acceptor = new NioSocketAcceptor();//为接收器设置管理服务acceptor.setHandler(new MyIoHandlerAdapter());//绑定端口acceptor.bind(new InetSocketAddress(PORT));// 设置过滤器(使用Mina提供的文本换行符编解码器)acceptor.getFilterChain().addLast("codec",new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"), LineDelimiter.WINDOWS.getValue(),LineDelimiter.WINDOWS.getValue())));//设置读取数据的缓冲区大小acceptor.getSessionConfig().setReadBufferSize(1024);//读写通道10秒内无操作进入空闲状态acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);logger.info("服务器启动成功... 端口号为:" + PORT);} catch (Exception e) {logger.error("服务器启动异常...", e);e.printStackTrace();}}}
服务器Log
//相当于将服务器分成了七个状态,而每个状态都有自己的一套逻辑处理方案。也可 implements IoHandlerpublic class MyIoHandlerAdapter extends IoHandlerAdapter {//日志类的实现public static Logger logger = Logger.getLogger(MyIoHandlerAdapter.class);//当一个Session 对象被创建的时候被调用。对于TCP 连接来说,连接被接受的时候调用,但要注意此时TCP 连接并未建立//对于UDP 来说,当有数据包收到的时候回调这个方法,因为UDP 是无连接的。@Overridepublic void sessionCreated(IoSession session) throws Exception {logger.info("服务器与客户端创建连接...session.getId()="+session.getId());super.sessionCreated(session);}//在连接被打开时调用,它总是在sessionCreated()方法之后被调用。//对于TCP 来 说,它是在连接被建立之后调用,你可以在这里执行一些认证操作、发送数据等。@Overridepublic void sessionOpened(IoSession session) throws Exception {logger.info("服务器与客户端连接打开...");super.sessionOpened(session);}//接收到消息时调用的方法,也就是用于接收消息的方法//一般情况下,message 是一个IoBuffer 类,如果你使用了协议编解码器,那么可以强制转换为你需要的类型。@Overridepublic void messageReceived(IoSession session, Object message) throws Exception {String msg = message.toString();//如果客户端发来exit,则关闭该连接if ("exit".equals(msg)) session.close(true);//向客户端发送消息Date date = new Date();session.write(date);logger.info("服务器接受消息成功...message="+msg);super.messageReceived(session, message);}//当发送消息成功时调用这个方法,注意这里的措辞"发送成功之后",也就是说发送消息是不能用这个方法的。@Overridepublic void messageSent(IoSession session, Object message) throws Exception {logger.info("服务器发送消息成功...message="+message.toString());super.messageSent(session, message);}//***********************************************************************************************************//这个方法在IoSession 的通道进入空闲状态时调用,对于UDP 协议来说,这个方法始终不会被调用。@Overridepublic void sessionIdle(IoSession session, IdleStatus status) throws Exception {logger.info("服务器进入空闲状态...status="+status);super.sessionIdle(session, status);}//对于TCP 来说,连接被关闭时,调用这个方法。对于UDP 来说,IoSession 的close()方法被调用时才会回掉这个方法。@Overridepublic void sessionClosed(IoSession session) throws Exception {logger.info("服务器与客户端断开连接...");super.sessionClosed(session);}//这个方法在你的程序、Mina 自身出现异常时回调,一般这里是关闭IoSession。@Overridepublic void exceptionCaught(IoSession session, Throwable cause) throws Exception {logger.info("服务器发送异常...");super.exceptionCaught(session, cause);}}
客户端Activity
public class MainActivity extends Activity implements OnClickListener {private EditText et;private Button send;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);et = (EditText) findViewById(R.id.et);send = (Button) findViewById(R.id.send);send.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.send:send();break;}}private void send() {final String content = et.getText().toString().trim();if (TextUtils.isEmpty(content)) {Toast.makeText(this, "内容不能为空", Toast.LENGTH_SHORT).show();return;}new MinaThread(content).start();}}
客户端连接
public class MinaThread extends Thread {private static final String HOST = "192.168.31.165";private static final int PORT = 4445;private IoSession session;private String content;public MinaThread(String content) {this.content = content;}@Overridepublic void run() {Log.d("TEST", "客户端链接开始...");IoConnector connector = new NioSocketConnector();//设置链接超时时间connector.setConnectTimeoutMillis(30000);//添加过滤器//connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new CharsetCodecFactory()));connector.getFilterChain().addLast("codec",new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"), LineDelimiter.WINDOWS.getValue(),LineDelimiter.WINDOWS.getValue())));connector.setHandler(new MyIoHandlerAdapter());ConnectFuture future = connector.connect(new InetSocketAddress(HOST, PORT));//创建链接future.awaitUninterruptibly();// 等待连接创建完成session = future.getSession();//获得sessionsession.write(content);session.getCloseFuture().awaitUninterruptibly();//等待连接断开Log.d("TEST", "客户端断开...");connector.dispose();super.run();}}
客户端日志
public class MyIoHandlerAdapter extends IoHandlerAdapter {@Overridepublic void messageReceived(IoSession session, Object message) throws Exception {String msg = message.toString();Log.d("bqt", "messageReceived:" + msg);super.messageReceived(session, message);}//******************************************************************************************@Overridepublic void messageSent(IoSession session, Object message) throws Exception {Log.d("bqt", "messageSent...");super.messageSent(session, message);}@Overridepublic void sessionClosed(IoSession session) throws Exception {Log.d("bqt", "sessionClosed...");super.sessionClosed(session);}@Overridepublic void sessionCreated(IoSession session) throws Exception {Log.d("bqt", "sessionCreated...");super.sessionCreated(session);}@Overridepublic void sessionOpened(IoSession session) throws Exception {Log.d("bqt", "sessionOpened...");super.sessionOpened(session);}@Overridepublic void sessionIdle(IoSession session, IdleStatus status) throws Exception {Log.d("bqt", "sessionIdle...");super.sessionIdle(session, status);}@Overridepublic void exceptionCaught(IoSession session, Throwable cause) throws Exception {Log.d("bqt", "exceptionCaught...");super.exceptionCaught(session, cause);}}
附件列表
Android集成Mina NIO Socket的更多相关文章
- Mina入门教程(二)----Spring4 集成Mina
在spring和mina集成的时候,要十分注意一个问题:版本. 这是一个非常严重的问题,mina官网的demo没错,网上很多网友总结的代码也是对的,但是很多人将mina集成到spring中的时候,总是 ...
- 基于libevent, libuv和android Looper不断演进socket编程 - 走向架构师之路 - 博客频道 - CSDN.NET
基于libevent, libuv和android Looper不断演进socket编程 - 走向架构师之路 - 博客频道 - CSDN.NET 基于libevent, libuv和android L ...
- [置顶]
spring集成mina 实现消息推送以及转发
spring集成mina: 在学习mina这块时,在网上找了很多资料,只有一些demo,只能实现客户端向服务端发送消息.建立长连接之类.但是实际上在项目中,并不简单实现这些,还有业务逻辑之类的处理以及 ...
- Java nio socket与as3 socket(粘包解码)连接的应用实例
对Java nio socket与as3 socket连接的简单应用 <ignore_js_op>Java nio socket与as3 socket连接的应用实例.rar (9.61 K ...
- 使用IntelliJ IDEA 13搭建Android集成开发环境(图文教程)
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...
- Android开发新手学习总结(一)——使用Android Studio搭建Android集成开发环境
[新手连载]一:使用Android Studio搭建Android集成开发环境http://bbs.itcast.cn/forum.php?mod=viewthread&tid=87055&a ...
- android firmware 利用UDP socket发送Magic Packet--python版本
android firmware 利用UDP socket发送Magic Packet--python版本 #!/usr/bin/python import sys, time from struct ...
- android firmware 利用UDP socket发送Magic Packet--c语言版本
android firmware 利用UDP socket发送Magic Packet 1 Magic Packet格式: 6个0xFF + 16个Dst Mac Address 2 代码需要设置目的 ...
- 使用Android Studio搭建Android集成开发环境(图文教程)
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...
随机推荐
- ubuntu系统mysql.h no such file or directory
在Ubuntu系统中,你已经安装了mysql,即你使用sudo apt-get install mysql-server mysql-client然而使用C语言访问mysql数据库时,却发现出现了如下 ...
- Win7下安装Ubuntu双系统常见问题
[转自己以前的文章] 导航: ● win7下硬盘安装ubuntu常见问题 ● win7下u盘安装ubuntu常见问题 吐槽: Ubuntu的安装花了我将近15个小时,网上常见的.不常见的问题基本我都 ...
- Centos7下Intel与AMD双显卡驱动的安装
前2天,在Nvidia单显卡上成功安装上了NVIdia的驱动,一时兴起,拿出另外的一个HP笔记本也准备装上驱动,悲催的是HP的显卡是AMD的,更加.更加悲催的是还是Intel+AMD的双显卡.网络 ...
- 字符串处理——strpos()函数
strpos() 函数返回字符串在另一个字符串中第一次出现的位置. 大小写敏感 如果没有找到该字符串,则返回 false. strpos(string,find,start) string 必需:规 ...
- eval("("+json对象+")")
var obj=eval("("+data+")"); 看看下面这条,应该能想到json的数据结构“+(json对象名)+”由于json是以”{}”的方式来开始 ...
- 【转】.NET开发者必备的11款免费工具
摘要:本文介绍一些最适合.NET开发人员简化Web开发的最佳工具,这些工具都是开源的,有的开发工具你既可以从网上下载可执行文件,也可以下载源代码.一些工具拥有可扩展的框架,是一个持续集成工具. 原文链 ...
- MongoDB学习--高级查询 [聚合Group]
Group大约需要一下几个参数. key:用来分组文档的字段.和keyf两者必须有一个 keyf:可以接受一个javascript函数.用来动态的确定分组文档的字段.和key两者必须有一个 initi ...
- Delphi-CompareStr 函数
函数名称 CompareStr 所在单元 System.SysUtils 函数原型 function CompareStr(const S1, S2: string): Integer; 函数功能 比 ...
- day05
1.递归 利用递归实现阶乘(1*2*3*4*5*6*7) def func(num): if num == 1: return 1 return num * func(num-1) x = func( ...
- What qualities characterize a great PhD student
省理工计算机教授David Karger接触了许多世界上最杰出的博士生,近日总结出了优秀博士通常具备的五点品质:0 过人的智力 1 好奇心 2 创造力 3 纪律性与生产力 4 与观众沟通 5 与伙伴沟 ...
不知道你们注意到了没,客户端的代码与服务器端的极其相似,不同的是服务器是创建NioSocketAcceptor对象,而客户端是创建NioSocketConnect对象。当然同样需要添加编码解码过滤器和业务逻辑过滤器。
问题:
服务端能收到也能发出消息,但客户端没有任何日志