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

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

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

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

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

服务端代码:

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

逻辑处理:

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

客户端代码:

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

逻辑处理:

Java代码
  1. packageorg.demo;
  2. importorg.apache.mina.common.IdleStatus;
  3. importorg.apache.mina.common.IoHandlerAdapter;
  4. importorg.apache.mina.common.IoSession;
  5. importorg.slf4j.Logger;
  6. importorg.slf4j.LoggerFactory;
  7. publicclassDemo1ClientHandlerextendsIoHandlerAdapter{
  8. privatestaticLoggerlogger=LoggerFactory
  9. .getLogger(Demo1ClientHandler.class);
  10. staticStringini="";
  11. @Override
  12. publicvoidmessageReceived(IoSessionsession,Objectmessage)
  13. throwsException{
  14. System.out.println(message);
  15. System.out.println(11);
  16. Stringmsg=message.toString();
  17. Stringinfo="";
  18. if("1".equals(msg)){
  19. //session.close();//用户登录成功关闭连接
  20. info="登录成功";
  21. }else{
  22. info="登录失败";
  23. }
  24. ini=info;
  25. session.setAttribute("state",info);
  26. session.close();
  27. System.out.println(12);
  28. //finalHelloWorldh=newHelloWorld();
  29. //h.DisplayToast(info);
  30. logger.info("客户端接收到的信息为:"+msg);
  31. }
  32. @Override
  33. publicvoidexceptionCaught(IoSessionsession,Throwablecause)
  34. throwsException{
  35. logger.error("客户端发生异常...",cause);
  36. }
  37. @Override
  38. publicvoidsessionCreated(IoSessionarg0)throwsException{
  39. //TODOAuto-generatedmethodstub
  40. }
  41. @Override
  42. publicvoidsessionIdle(IoSessionarg0,IdleStatusarg1)throwsException{
  43. //TODOAuto-generatedmethodstub
  44. }
  45. /**
  46. *这个方法在连接被打开时调用,它总是在sessionCreated()方法之后被调用。对于TCP来
  47. *说,它是在连接被建立之后调用,你可以在这里执行一些认证操作、发送数据等。
  48. */
  49. @Override
  50. publicvoidsessionOpened(IoSessionarg0)throwsException{
  51. logger.info("ok","iamready!");
  52. System.out.println(6);
  53. }
  54. }

更多相关文章

  1. Android开发之Java设计模式基础篇
  2. android reboot 功能的添加
  3. React-Native:调用(Android)Native方法
  4. Android(安卓)UI开发 View自绘控件 分享
  5. Android(安卓)Activity之间切换出现短暂黑屏的处理方法
  6. android横竖屏切换(复制未整理)
  7. Android大图加载方法
  8. android 自定义View之SubmitView
  9. Android(安卓)开发杂记

随机推荐

  1. Android(安卓)layout布局属性、标签属性
  2. android中的tab小结
  3. ADT版本更新失败,降级
  4. android布局属性详解
  5. Android中ClipDrawable的用法
  6. ERROR: Missing source image for "splas
  7. Android(安卓)短信 彩信 wap push的接收
  8. Android——程序移植 相关知识总结贴
  9. Android常用开源库(UI部分)
  10. Android(安卓)xml 深入解析shape