`
00zhengfu00
  • 浏览: 6177 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

android之mina框架通信学习

阅读更多

这几天刚学期android,目前项目要求的客户端是android平台,所以要开始啃了....

服务器与客户端的通信准备使用现有的开发框架,找了几个----mina,google 的 protobuf,smack,androidpn,Netty...

这些框架都不错,不过最终选择的是apache的mina框架,主要是mina在网上的资料比较全,用的也比较广泛,再就是也适合我项目以后的扩展加入SPRING\CXF\RESTFUL WEBSERVICE等

不废话了,开始把目前学习的进度开始进行整理,方便自己以后进行查阅,也给其他入门的兄弟们 参考参考。

当然,最重要的是希望大家能够提出并给与宝贵的经验。

 

服务端代码:

Java代码  收藏代码
  1. package org.demo;  
  2.   
  3. import java.net.InetSocketAddress;  
  4. import java.nio.charset.Charset;  
  5.   
  6. import org.apache.mina.common.IdleStatus;  
  7. import org.apache.mina.common.IoAcceptor;  
  8. import org.apache.mina.filter.codec.ProtocolCodecFilter;  
  9. import org.apache.mina.filter.codec.textline.LineDelimiter;  
  10. import org.apache.mina.filter.codec.textline.TextLineCodecFactory;  
  11. import org.apache.mina.transport.socket.nio.NioSocketAcceptor;  
  12. import org.slf4j.Logger;  
  13. import org.slf4j.LoggerFactory;  
  14.   
  15.   
  16. public class Demo1Server {  
  17.     private static Logger logger = LoggerFactory.getLogger(Demo1Server.class);  
  18.   
  19.     private static int PORT = 8989;  
  20.   
  21.     public static void main(String[] args) {  
  22.         IoAcceptor acceptor = null;  
  23.         try {  
  24.               
  25.             // 创建一个非阻塞的server端的Socket  
  26.             acceptor = new NioSocketAcceptor();  
  27.             // 设置过滤器(使用Mina提供的文本换行符编解码器)  
  28.             acceptor.getFilterChain().addLast(  
  29.                     "codec",  
  30.                     new ProtocolCodecFilter(new TextLineCodecFactory(Charset  
  31.                             .forName("UTF-8"),  
  32.                             LineDelimiter.WINDOWS.getValue(),  
  33.                             LineDelimiter.WINDOWS.getValue())));  
  34.               
  35.             // 设置读取数据的缓冲区大小  
  36.             acceptor.getSessionConfig().setReadBufferSize(2048);  
  37.             // 读写通道10秒内无操作进入空闲状态  
  38.             acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);  
  39.             // 绑定逻辑处理器  
  40.             acceptor.setHandler(new Demo1ServerHandler());  
  41.             // 绑定端口  
  42.             acceptor.bind(new InetSocketAddress(PORT));  
  43.             logger.info("服务端启动成功...     端口号为:" + PORT);  
  44.         } catch (Exception e) {  
  45.             logger.error("服务端启动异常....", e);  
  46.             e.printStackTrace();  
  47.         }  
  48.     }  
  49. }  

 逻辑处理:

Java代码  收藏代码
  1. package org.demo;  
  2. import java.util.Date;  
  3.   
  4. import net.sf.json.JSONObject;  
  5.   
  6. import org.apache.mina.common.IdleStatus;  
  7. import org.apache.mina.common.IoHandlerAdapter;  
  8. import org.apache.mina.common.IoProcessor;  
  9. import org.apache.mina.common.IoSession;  
  10. import org.apache.mina.transport.socket.nio.NioProcessor;  
  11. import org.slf4j.Logger;  
  12. import org.slf4j.LoggerFactory;  
  13.   
  14. public class Demo1ServerHandler extends IoHandlerAdapter{  
  15.     public static Logger logger = LoggerFactory.getLogger(Demo1ServerHandler.class);  
  16.   
  17.     /**  
  18.     * 这个方法当一个Session 对象被创建的时候被调用。对于TCP 连接来说,连接被接受的时候  
  19.     * 调用,但要注意此时TCP 连接并未建立,此方法仅代表字面含义,也就是连接的对象  
  20.     * IoSession 被创建完毕的时候,回调这个方法。  
  21.     * 对于UDP 来说,当有数据包收到的时候回调这个方法,因为UDP 是无连接的。  
  22.     */   
  23.     @Override  
  24.     public void sessionCreated(IoSession session) throws Exception {  
  25.         logger.info("服务端与客户端创建连接...");  
  26.     }  
  27.   
  28.     /**  
  29.     * 这个方法在连接被打开时调用,它总是在sessionCreated()方法之后被调用。对于TCP 来  
  30.     * 说,它是在连接被建立之后调用,你可以在这里执行一些认证操作、发送数据等。  
  31.     */   
  32.     @Override  
  33.     public void sessionOpened(IoSession session) throws Exception {  
  34.         logger.info("服务端与客户端连接打开...");  
  35.     }  
  36.   
  37.     /**  
  38.     * 接收到消息时调用的方法,也就是用于接收消息的方法,一般情况下,message 是一个  
  39.     * IoBuffer 类,如果你使用了协议编解码器,那么可以强制转换为你需要的类型。  
  40.     */   
  41.     @Override  
  42.     public void messageReceived(IoSession session, Object message)  
  43.             throws Exception {  
  44.         /* 
  45.          String msg = message.toString(); 
  46.         //读取数据 
  47.         logger.info("服务端接收到的数据为:" + msg+"客户端ip:"+session.getLocalAddress()); 
  48.         if ("bye".equals(msg)) { // 服务端断开连接的条件 
  49.             session.close(); 
  50.         } 
  51.         Date date = new Date(); 
  52.         session.write(date);*/  
  53.         JSONObject jsonObject = JSONObject.fromObject(message.toString());  
  54.         String username;   
  55.         String sex;   
  56.         String qq;   
  57.         String score;   
  58.         String nickname;  
  59.         username = jsonObject.getString("username");   
  60.         sex = jsonObject.getString("sex");   
  61.         qq = jsonObject.getString("QQ");   
  62.         score = jsonObject.getString("Min.score");  
  63.         nickname = jsonObject.getString("nickname");  
  64.         int state = login(username);  
  65.         String msg = "登录成功!";  
  66.         if(state == 0){  
  67.             msg = "登录失败!";  
  68.         }  
  69.         logger.info("用户:" + username + msg);  
  70.           
  71.         //模拟登陆  
  72.         if ("bye".equals(nickname)) { // 服务端断开连接的条件  
  73.             session.close();  
  74.         }  
  75.         //Date date = new Date();  
  76.         session.write(state);  
  77.     }  
  78.   
  79.     //验证用户名 与 密码  
  80.         public int login(String message){  
  81.             if("sysadmin".equals(message)){  
  82.                 return 1;  
  83.             }  
  84.             return 0;  
  85.         }  
  86.           
  87.     /**  
  88.     * 当发送消息成功时调用这个方法,注意这里的措辞,发送成功之后,  
  89.     * 也就是说发送消息是不能用这个方法的。  
  90.     */   
  91.     @Override  
  92.     public void messageSent(IoSession session, Object message) throws Exception {  
  93.         logger.info("服务端发送信息成功...");  
  94.     }  
  95.   
  96.     /**  
  97.     * 对于TCP 来说,连接被关闭时,调用这个方法。  
  98.     * 对于UDP 来说,IoSession 的close()方法被调用时才会毁掉这个方法。  
  99.     */   
  100.     @Override  
  101.     public void sessionClosed(IoSession session) throws Exception {  
  102.         logger.info("服务端连接已经失效");  
  103.     }  
  104.   
  105.     /**  
  106.     * 这个方法在IoSession 的通道进入空闲状态时调用,对于UDP 协议来说,这个方法始终不会  
  107.     * 被调用。  
  108.     */   
  109.     @Override  
  110.     public void sessionIdle(IoSession session, IdleStatus status)  
  111.             throws Exception {  
  112.         logger.info("服务端进入空闲状态...");  
  113.     }  
  114.   
  115.     /**  
  116.     * 这个方法在你的程序、Mina 自身出现异常时回调,一般这里是关闭IoSession。  
  117.     */   
  118.     @Override  
  119.     public void exceptionCaught(IoSession session, Throwable cause)  
  120.             throws Exception {  
  121.         logger.error("服务端发送异常...", cause);  
  122.     }  
  123.   
  124. }  

 客户端代码:

Java代码  收藏代码
  1. package org.demo;  
  2.   
  3. import java.net.InetSocketAddress;  
  4. import java.nio.charset.Charset;  
  5. import java.util.Timer;  
  6. import java.util.TimerTask;  
  7.   
  8. import org.apache.mina.common.ConnectFuture;  
  9. import org.apache.mina.common.IoConnector;  
  10. import org.apache.mina.common.IoSession;  
  11. import org.apache.mina.filter.codec.ProtocolCodecFilter;  
  12. import org.apache.mina.filter.codec.textline.LineDelimiter;  
  13. import org.apache.mina.filter.codec.textline.TextLineCodecFactory;  
  14. import org.apache.mina.transport.socket.nio.NioSocketConnector;  
  15. import org.json.JSONException;  
  16. import org.json.JSONObject;  
  17. import org.slf4j.Logger;  
  18. import org.slf4j.LoggerFactory;  
  19.   
  20. import android.app.Activity;  
  21. import android.content.Context;  
  22. import android.os.Bundle;  
  23. import android.os.Handler;  
  24. import android.os.HandlerThread;  
  25. import android.os.Message;  
  26. import android.view.View;  
  27. import android.view.View.OnClickListener;  
  28. import android.widget.Button;  
  29. import android.widget.EditText;  
  30. import android.widget.Toast;  
  31.   
  32. /** 
  33.  * @author wangmiao 
  34.  * @version 创建时间:2012-4-24 下午10:57:53 简单说明 
  35.  */  
  36. public class HelloWorld2 extends Activity {  
  37.     private static Logger logger = LoggerFactory.getLogger(HelloWorld2.class);  
  38.     private static String HOST = "192.168.1.100";  
  39.   
  40.     private static int PORT = 8989;  
  41.     private static String LOGIN_NAME = "";  
  42.   
  43.     public HelloWorld2() {  
  44.   
  45.     }  
  46.     Handler handler = new Handler();  
  47.   
  48.   
  49.     @Override  
  50.     protected void onCreate(Bundle savedInstanceState) {  
  51.         // TODO Auto-generated method stub  
  52.         super.onCreate(savedInstanceState);  
  53.         setContentView(R.layout.main);  
  54.         System.out.println(1);  
  55.         /* 
  56.          * new Thread() { public void run() { socketServer(); } }.start(); 
  57.          */  
  58.         Button btn = (Button) findViewById(R.id.button1);  
  59.         btn.setOnClickListener(new OnClickListener() {  
  60.             EditText name = (EditText) findViewById(R.id.username);  
  61.               
  62.             @Override  
  63.             public void onClick(View v) {  
  64.                 // TODO Auto-generated method stub  
  65.                 //name.setText("sysadmin"); 设置初始值  
  66.                 final Handler myHandler = new Handler(){  
  67.                     int i = 0;  
  68.                     @Override  
  69.                     public void handleMessage(Message msg) { //该线程位于主线程  
  70.                         // TODO Auto-generated method stub  
  71.                         //如果该消息是本程序所发送的  
  72.                         if(msg.what == 0x1233){  
  73.                             //主线程里面 显示操作  
  74.                             i++;  
  75.                             showToast("第"+i+"次连接开始....");  
  76.                         }  
  77.                     }  
  78.                 };  
  79.                 //定义一个计时器,让该计时器周期性的执行指定任务 TimerTask对象的本质就是启动一条新线程  
  80.                 new Timer().schedule(new TimerTask()  
  81.                 {  
  82.                     @Override  
  83.                     public void run() {  
  84.                         //新启动的线程无法访问该Activity里的组件  
  85.                         //所以需要通过Handler发送消息  
  86.                         // TODO Auto-generated method stub  
  87.                         Message msg = new Message();  
  88.                         msg.what = 0x1233;  
  89.                         //发送消息  
  90.                         myHandler.sendMessage(msg);  
  91.                           
  92.                         LOGIN_NAME = name.getText().toString();  
  93.                         //在子线程里面发送请求   
  94.                         socketServer();  
  95.                     }  
  96.                 },0,10000);  
  97.                 //  
  98.                 /*// 压力测试 10s秒钟 执行一次 
  99.                 while(true){ 
  100.                     new Thread(){ 
  101.                         public  void run(){ 
  102.                             socketServer(); 
  103.                         } 
  104.                     }.start(); 
  105.                     try { 
  106.                         Thread.sleep(10000); 
  107.                     } catch (InterruptedException e) { 
  108.                         // TODO Auto-generated catch block 
  109.                         e.printStackTrace(); 
  110.                     } 
  111.                 }*/  
  112.             }  
  113.         });  
  114.         System.out.println(1000);  
  115.     }  
  116.   
  117.   
  118.     public  void showToast(final String text) {  
  119.           handler.post(new Runnable() {  
  120.            @Override  
  121.            public void run() {  
  122.             Toast.makeText(getApplicationContext(), text,  
  123.               Toast.LENGTH_SHORT).show();  
  124.   
  125.            }  
  126.           });  
  127.     }  
  128.   
  129.     public void socketServer() {  
  130.         // 创建一个非阻塞的客户端程序  
  131.         System.out.println(2);  
  132.         IoConnector connector = new NioSocketConnector();  
  133.         // 设置链接超时时间  
  134.         System.out.println(3);  
  135.         connector.setConnectTimeout(5);  
  136.         System.out.println(4);  
  137.         // 添加过滤器  
  138.         connector.getFilterChain().addLast(  
  139.                 "codec",  
  140.                 new ProtocolCodecFilter(new TextLineCodecFactory(Charset  
  141.                         .forName("UTF-8"), LineDelimiter.WINDOWS.getValue(),  
  142.                         LineDelimiter.WINDOWS.getValue())));  
  143.         // 添加业务逻辑处理器类  
  144.         connector.setHandler(new Demo1ClientHandler());  
  145.         IoSession session = null;  
  146.         try {  
  147.             System.out.println(5);  
  148.             System.out.println(HOST + "|" + PORT);  
  149.             // 这里是异步操作 连接后立即返回  
  150.             ConnectFuture future = connector.connect(new InetSocketAddress(  
  151.                     HOST, PORT));// 创建连接  
  152.             System.out.println(6);  
  153.             future.awaitUninterruptibly();// 等待连接创建完成   
  154.             System.out.println(7);  
  155.             session = future.getSession();// 获得session  
  156.             // session.setAttribute(arg0, arg1)  
  157.             String jsonStr = "{\"people\":["  
  158.                     + "{ \"firstName\": \"问你t\", \"lastName\":\"McLaughlin\",\"email\": \"aaaa\" } ,"  
  159.                     + "{ \"firstName\": \"Brett\", \"lastName\":\"McLaughlin\",\"email\": \"aaaa\" } ,] } ";  
  160.             JSONObject json = createJSONObject();  
  161.   
  162.             // 根据key返回一个字符串  
  163.             // //String username = json.getString("username");  
  164.             // System.out.println("username==>"+username);  
  165.             System.out.println(8);  
  166.             session.write(json);// 发送消息  
  167.             System.out.println(9);  
  168.               
  169.              session.getCloseFuture().awaitUninterruptibly();// 等待连接断开  
  170.              connector.dispose();  
  171.              System.out.println(Demo1ClientHandler.ini);  
  172.              showToast(Demo1ClientHandler.ini);  
  173.         } catch (Exception e) {  
  174.             showToast("客户端链接异常,请检查网络");  
  175.             logger.error("客户端链接异常...", e);  
  176.         }  
  177.           
  178.     }  
  179.   
  180.     public static JSONObject createJSONObject() {  
  181.         JSONObject jsonObject = new JSONObject();  
  182.         try {  
  183.             jsonObject.put("username", LOGIN_NAME);  
  184.             jsonObject.put("sex""男");  
  185.             jsonObject.put("QQ""413425430");  
  186.             jsonObject.put("Min.score"new Integer(99));  
  187.             jsonObject.put("nickname""梦中心境");  
  188.         } catch (JSONException e) {  
  189.             // TODO Auto-generated catch block  
  190.             e.printStackTrace();  
  191.         }  
  192.         return jsonObject;  
  193.     }  
  194. }  
wangmiao 写道
这里客户端运用了 Handler消息的传递机制,主要是为了解决android应用的多线程问题--Android平台不允许Activity新启动的线程访问该Activity里的界面组件,这样就会导致新启动的线程无法改变界面组件的属性值。 
Handler类的主要作用有两个:1.新启动的线程中发送消息 2.在线程中获取、处理消息 
具体的关于Handler类的的使用去看相关的帮助说明。

 

  

 

逻辑处理:

Java代码  收藏代码
  1. package org.demo;  
  2.   
  3. import org.apache.mina.common.IdleStatus;  
  4. import org.apache.mina.common.IoHandlerAdapter;  
  5. import org.apache.mina.common.IoSession;  
  6. import org.slf4j.Logger;  
  7. import org.slf4j.LoggerFactory;  
  8.   
  9.   
  10. public class Demo1ClientHandler extends IoHandlerAdapter {  
  11.     private static Logger logger = LoggerFactory  
  12.             .getLogger(Demo1ClientHandler.class);  
  13.   
  14.     static String ini = "";  
  15.     @Override  
  16.     public void messageReceived(IoSession session, Object message)  
  17.             throws Exception {  
  18.         System.out.println(message);  
  19.         System.out.println(11);  
  20.         String msg = message.toString();  
  21.         String info = "";  
  22.         if ("1".equals(msg)) {  
  23.             // session.close(); //用户登录成功 关闭连接  
  24.             info = "登录成功";  
  25.         } else {  
  26.             info = "登录失败";  
  27.         }  
  28.         ini = info;  
  29.         session.setAttribute("state", info);  
  30.         session.close();  
  31.         System.out.println(12);  
  32.     //   final HelloWorld h = new HelloWorld();  
  33.         // h.DisplayToast(info);  
  34.         logger.info("客户端接收到的信息为:" + msg);  
  35.     }  
  36.   
  37.   
  38.   
  39.     @Override  
  40.     public void exceptionCaught(IoSession session, Throwable cause)  
  41.             throws Exception {  
  42.   
  43.         logger.error("客户端发生异常...", cause);  
  44.     }  
  45.   
  46.     @Override  
  47.     public void sessionCreated(IoSession arg0) throws Exception {  
  48.         // TODO Auto-generated method stub  
  49.     }  
  50.   
  51.     @Override  
  52.     public void sessionIdle(IoSession arg0, IdleStatus arg1) throws Exception {  
  53.         // TODO Auto-generated method stub  
  54.     }  
  55.   
  56.     /**  
  57.     * 这个方法在连接被打开时调用,它总是在sessionCreated()方法之后被调用。对于TCP 来  
  58.     * 说,它是在连接被建立之后调用,你可以在这里执行一些认证操作、发送数据等。  
  59.     */    
  60.     @Override  
  61.     public void sessionOpened(IoSession arg0) throws Exception {  
  62.         logger.info("ok""i am ready!");  
  63.         System.out.println(6);  
  64.     }  
  65. }  
  • 大小: 21.2 KB
  • 大小: 22 KB
  • 大小: 23.1 KB
分享到:
评论

相关推荐

    基于Android开发MINA框架使用详解

    详细讲解如何使用MINA配合Android客户端实现聊天功能,解决中文乱码问题,解决Android客户端接收不到消息问题

    Mina框架在android上的使用范例

    如何使用mina框架简化android端TCP通信的开发

    Mina长连接框架实现Android客户端与服务器端通信

    Mina长连接框架实现Android客户端与服务器端通信

    apache-mina 即时通信框架,加入SSH和android包

    这个框架协议自己定义(即:底层已有字符串传输或Object传输,自己可以定义字符串会对象进行解析来制定自己的协议) 语音、图片等其实也是上传文件服务器再连个即时通信字符串通信而已; 注意:SSH-lib里有注意...

    Mina通信Demo

    Android手机端做服务器和客户端,使用MINA通信的demo,通过Demo可以清晰的看到Android平台使用Mina框架处理Socket通信的方法。

    MinaForAndroid:基于Mina的android通信框架,通过封装实现RPC通信,功能仍在完善中

    MinaForAndroid基于Mina的android通信框架,通过封装实现RPC通信,旨在打造一个如下功能的通信框架:1.可扩展的RPC通信,客户端和服务端之间可自定义通信接口(在此套用Android框架层的概念叫做service服务)。自定义...

    一款Android平台UDP双向通信源码

    本源码是《NIO框架入门(四):Android与MINA2、Netty4的跨平台UDP双向通信实战》文中的代码,详见:http://www.52im.net/thread-388-1-1.html

    mina通信服务器端客户端源码.rar

    代码利用mina框架实现了服务器端和客户端,客户端的登录请求、客户端向服务器端请求图片文件的功能。代码分为服务端和客户端,开发环境eclipse。服务器代码可在web项目中使用,客户端代码可以在Android开发时使用,...

    Android网络通信的实现方式

    Android网络编程分为两种:基于http协议的,和基于socket的。...(3)Apache Mina框架 一、HttpURLConnection的实现方式 String response = null; Url url = new URL(path); HttpURLConnection connectio

    android聊天项目

    基于MINA框架的 UDP通信实现的简单 Android聊天项目,androi客户端是用原生方式写的。

    基于Netty的Android点对点聊天软件-源码

    基于Netty的Android点对点聊天软件-源码 Netty是基于NIO的JAVA异步通讯框架,比Mina在性能上更具有优势,其作者也正是Mina的原作者之一。

    JAVA上百实例源码以及开源项目源代码

     Java数据压缩与传输实例,可以学习一下实例化套按字、得到文件输入流、压缩输入流、文件输出流、实例化缓冲区、写入数据到文件、关闭输入流、关闭套接字关闭输出流、输出错误信息等Java编程小技巧。 Java数组倒置...

    java开源包1

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包11

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包2

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包3

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包6

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包5

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包10

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包4

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

Global site tag (gtag.js) - Google Analytics