Android 通过Socket 和服务器通讯
来源:互联网 发布:网络缓存文件夹在哪里 编辑:程序博客网 时间:2024/06/03 14:51
Android 通过Socket 和服务器通讯,是一种比较常用的通讯方式,时间比较紧,说下大致的思路,希望能帮到使用socket 进行通信的人
(1)开启一个线程发送消息 SocketOutputThread
消息是放在队列里的,当有消息后,进入队列,线程唤醒,发送消息,并反馈发送是否成功的回调
(2)开启一个线程接受服务器消息 SocketInputThread
为了防止一直收数据,浪费电池的电,采用NIO的方式读socket的数据,这个是本文的关键
(3)开启一个线程,做心跳,防止socket连接终断 , SocketHeartThread
(4)构建 SocketThreadManager对以上三个thread进行管理
(5)构建 TCPClient 发送socket消息
在NIO的方式实现TCP,特别是在接收服务器的数据,不用写个线程定时去读了。
本文地址(http://www.cnblogs.com/likwo/p/3641135.html)
DEMO 截图
主要代码如下,详细代码在附件里。
SocketOutPutThread 类
package com.example.socketblockdemo;import java.io.IOException;import java.io.ObjectOutputStream;import java.net.Socket;import java.util.List;import java.util.concurrent.CopyOnWriteArrayList;import android.os.Bundle;import android.os.Handler;import android.os.Message;/** * 客户端写消息线程 * * @author way * */public class SocketOutputThread extends Thread{ private boolean isStart = true; private static String tag = "socketOutputThread"; private List<MsgEntity> sendMsgList; public SocketOutputThread( ) { sendMsgList = new CopyOnWriteArrayList<MsgEntity>(); } public void setStart(boolean isStart) { this.isStart = isStart; synchronized (this) { notify(); } } // 使用socket发送消息 public boolean sendMsg(byte[] msg) throws Exception { if (msg == null) { CLog.e(tag, "sendMsg is null"); return false; } try { TCPClient.instance().sendMsg(msg); } catch (Exception e) { throw (e); } return true; } // 使用socket发送消息 public void addMsgToSendList(MsgEntity msg) { synchronized (this) { this.sendMsgList.add(msg); notify(); } } @Override public void run() { while (isStart) { // 锁发送list synchronized (sendMsgList) { // 发送消息 for (MsgEntity msg : sendMsgList) { Handler handler = msg.getHandler(); try { sendMsg(msg.getBytes()); sendMsgList.remove(msg); // 成功消息,通过hander回传 if (handler != null) { Message message = new Message(); message.obj = msg.getBytes(); message.what =1; handler.sendMessage(message); // handler.sendEmptyMessage(1); } } catch (Exception e) { e.printStackTrace(); CLog.e(tag, e.toString()); // 错误消息,通过hander回传 if (handler != null) { Message message = new Message(); message.obj = msg.getBytes(); message.what = 0;; handler.sendMessage(message); } } } } synchronized (this) { try { wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }// 发送完消息后,线程进入等待状态 } } }}
SocketInputThread
package com.example.socketblockdemo;import java.io.IOException;import java.io.UnsupportedEncodingException;import java.nio.ByteBuffer;import java.nio.channels.CancelledKeyException;import java.nio.channels.ClosedSelectorException;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.SocketChannel;import java.nio.charset.CharacterCodingException;import java.nio.charset.Charset;import android.content.Intent;import android.text.TextUtils;/** * 客户端读消息线程 * * @author way * */public class SocketInputThread extends Thread{ private boolean isStart = true; private static String tag = "socket"; // private MessageListener messageListener;// 消息监听接口对象 public SocketInputThread() { } public void setStart(boolean isStart) { this.isStart = isStart; } @Override public void run() { while (isStart) { // 手机能联网,读socket数据 if (NetManager.instance().isNetworkConnected()) { if (!TCPClient.instance().isConnect()) { CLog.e(tag, "TCPClient connet server is fail read thread sleep second" +Const.SOCKET_SLEEP_SECOND ); try { sleep(Const.SOCKET_SLEEP_SECOND * 1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } readSocket(); // 如果连接服务器失败,服务器连接失败,sleep固定的时间,能联网,就不需要sleep CLog.e("socket","TCPClient.instance().isConnect() " + TCPClient.instance().isConnect() ); } } } public void readSocket() { Selector selector = TCPClient.instance().getSelector(); if (selector == null) { return; } try { // 如果没有数据过来,一直柱塞 while (selector.select() > 0) { for (SelectionKey sk : selector.selectedKeys()) { // 如果该SelectionKey对应的Channel中有可读的数据 if (sk.isReadable()) { // 使用NIO读取Channel中的数据 SocketChannel sc = (SocketChannel) sk.channel(); ByteBuffer buffer = ByteBuffer.allocate(1024); try { sc.read(buffer); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); // continue; } buffer.flip(); String receivedString = ""; // 打印收到的数据 try { receivedString = Charset.forName("UTF-8") .newDecoder().decode(buffer).toString(); CLog.e(tag, receivedString); Intent i = new Intent(Const.BC); i.putExtra("response", receivedString); MainActivity.s_context.sendBroadcast(i ); } catch (CharacterCodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } buffer.clear(); buffer = null; try { // 为下一次读取作准备 sk.interestOps(SelectionKey.OP_READ); // 删除正在处理的SelectionKey selector.selectedKeys().remove(sk); } catch (CancelledKeyException e) { e.printStackTrace(); } } } } // selector.close(); // TCPClient.instance().repareRead(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } catch (ClosedSelectorException e2) { } } }
SocketHeartHread 心态类
View Code
线程管理类
package com.example.socketblockdemo;import android.os.Handler;import android.text.TextUtils;public class SocketThreadManager{ private static SocketThreadManager s_SocketManager = null; private SocketInputThread mInputThread = null; private SocketOutputThread mOutThread = null; private SocketHeartThread mHeartThread = null; // 获取单例 public static SocketThreadManager sharedInstance() { if (s_SocketManager == null) { s_SocketManager = new SocketThreadManager(); s_SocketManager.startThreads(); } return s_SocketManager; } // 单例,不允许在外部构建对象 private SocketThreadManager() { mHeartThread = new SocketHeartThread(); mInputThread = new SocketInputThread(); mOutThread = new SocketOutputThread(); } /** * 启动线程 */ private void startThreads() { mHeartThread.start(); mInputThread.start(); mInputThread.setStart(true); mOutThread.start(); mInputThread.setStart(true); // mDnsthread.start(); } /** * stop线程 */ public void stopThreads() { mHeartThread.stopThread(); mInputThread.setStart(false); mOutThread.setStart(false); } public static void releaseInstance() { if (s_SocketManager != null) { s_SocketManager.stopThreads(); s_SocketManager = null; } } public void sendMsg(byte [] buffer, Handler handler) { MsgEntity entity = new MsgEntity(buffer, handler); mOutThread.addMsgToSendList(entity); } }
TCPClient ,采用NIO的方式构建
View Code
如何使用
// 发送消息,失败或者成功的handler SocketThreadManager.sharedInstance().sendMsg(str.getBytes(), handler);
代码下载 http://files.cnblogs.com/likwo/SocketBlockDemo.zip
0 0
- Android 通过Socket 和服务器通讯
- Android 通过Socket 和服务器通讯
- Android 通过Socket 和服务器通讯
- Android 通过Socket 和服务器通讯
- WEB页面通过Socket和服务器通讯(上)
- Android基于客户端和服务器的Socket编程例子之Socket基础通讯--socket相关知识
- Android基于客户端和服务器的Socket编程例子之Socket基础通讯--socket模型使用
- php通过socket和c通讯
- Socket之服务器和客户端通讯
- 安卓客户端通过socket与服务器进行通讯
- C# Socket服务器通讯
- java--通过socket和多线程进行多个客服端与服务器的简单通讯--基于tcp
- Android socket AsyncTask和linux服务端通讯
- Android通过Socket(TCP/IP)与PC通讯
- Android通过Socket(TCP/IP)与PC通讯
- Android通过Socket(TCP/IP)与PC通讯
- Android通过Socket(TCP/IP)与PC通讯
- Android通过Socket(TCP/IP)与PC通讯
- 图的割点算法vs图的割边算法
- 内存和FLASH的区别总结
- SQL Server 数据库设计
- POJ 2186 Popular Cows(强连通,kosaraju算法)
- Cocos2d-x3.3Final(9)RichText常用成员函数(C++)
- Android 通过Socket 和服务器通讯
- Android Bitmap之Loading Large Bitmaps Efficiently
- caffe源码解析之Layer层(1)
- android 中处理崩溃异常并重启程序
- Linux操作命令(二)
- (转) Java内部类的使用小结
- Code[vs]1010过河卒(dfs不成+棋盘dp)
- JLayeredPane
- 变量作用域及内存