




已阅读5页,还剩3页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
基于线程池和NIO技术构建高效的多协议Android通讯框架 引言在多数涉及网络通讯的手机应用中,由于GPRS网络的速度在目前的情况下还不算理想,所以,如何能够高效的请求得到网络数据就成为大多数应用所面临的瓶颈问题。同时,在一些应用程序中可能会使用多种协议,比如IM通讯、视频流类型的应用会牺牲数据的完整性来更高效的获取数据,在这种类型的应用中,可能需要同时支持TCP、UDP以及HTTP协议。本文就尝试基于Android的多线程技术ThreadPoolExecutor以及NIO非阻塞式编程构建这样一个框架,以高效的获取网络数据并很好的支持多种协议的并发请求。基本设计思路既然是基于ThreadPoolExecutor线程池来管理多个NIO线程的请求的,那么首先应该有个全局的ThreadPoolExecutor变量,使用单例模式来实现:public static synchronized ThreadPoolExecutor setThreadPoolNum(int aThreadPoolMinNum,int aThreadPoolMaxNum,long keepAliveTime)if(threadPool = null)threadPool = new ThreadPoolExecutor(aThreadPoolMinNum,aThreadPoolMaxNum,keepAliveTime,TimeUnit.SECONDS,new ArrayBlockingQueue(3),new ThreadPoolExecutor.DiscardOldestPolicy(); return threadPool;每个NIO请求被设计为单独的线程,而每个网络通讯的连接都可以附属在NIO线程上,基本的设计思路如图1所示:图1NIO通讯线程的设计NIO通讯线程被设计为管理多个不同类型的网络连接,并负责维护每个连接所对应的网络数据处理接口,这些网络数据处理接口包括数据发送接口processWrite()、数据接收接口processRead()以及错误处理接口processError()等。在每个NIO通讯线程被线程池对象启动之后,首先检查NIO端口是否有连接注册的数据到来,如果有数据到来,则提交给相应的连接进行处理,代码如下:try if(selector != null) n = selector.select(3000); / 如果要shutdown,关闭selector退出 if (shutdown) selector.close(); break; catch (IOException e) dispatchErrorToAll(e); / 如果select返回大于0,处理事件if(n 0) for (Iterator i = selector.selectedKeys().iterator(); i.hasNext();) / 得到下一个KeySelectionKey sk = i.next();i.remove();/ 检查其是否还有效 if(!sk.isValid() continue; / 处理 INIOHandler handler = (INIOHandler)sk.attachment(); try if(sk.isConnectable() cessConnect(sk); else if (sk.isReadable() cessRead(sk); catch (IOException e) cessError(e); catch (RuntimeException e) n = 0; checkNewConnection(); notifySend(); 上面的代码首先使用Selector类的selectedKyes()方法获取到所有有事件发生的连接通道,然后遍历这些通道,并使用attachment()方法获取到注册到通道上的处理对象NIOHandler,之后调用每个连接通道上注册的NIOHandler对象的方法进行网络数据的处理。网络连接的设计从NIO通讯线程的设计中知道,每个网络连接都有相应的连接通道以及连接通道的数据处理器,那么就可以抽象出来这些连接通道以及数据处理器的接口:public interface IConnection /* * 添加一个包到发送队列 * * param out * OutPacket子类 */public void add(OutPacket out);public void clearSendQueue();public void start();public String getId();public void dispose();public InetSocketAddress getRemoteAddress();public SelectableChannel channel();public INIOHandler getNIOHandler();public boolean isEmpty();public void receive() throws IOException;public void send() throws IOException;public void send(ByteBuffer buffer); public boolean isConnected();在通道数据处理器中,每个连接通道都应该有基本的数据发送、数据接收以及错误处理接口,可以抽象出数据处理器的基本接口如下:public interface INIOHandler public void processConnect(SelectionKey sk) throws IOException; public void processRead(SelectionKey sk) throws IOException; public void processWrite() throws IOException; public void processError(Exception e);那么每个网络连接都应该继承上述两个接口,比如TCP连接需要有SocketChannel通道以及相应的NIOHandler数据处理接口,UDP连接需要有DatagramChannel通道以及相应的NIOHandler数据处理接口,下面是TCPConnection的代码:public class TCPConnection extends ConnectionImp/* 用于通信的channel */private final SocketChannel channel;/* * true表示远程已经关闭了这个连接 */private boolean remoteClosed;/* * 构造一个连接到指定地址的TCPPort. * * param address 连接到的地址. * throws IOException 端口打开/端口配置/连接到地址出错. */public TCPConnection(String id, InetSocketAddress address) throws IOException super(id); channel = SocketChannel.open(); channel.configureBlocking(false); this.remoteAddress = address; remoteClosed = false;public void start() try channel.connect(remoteAddress); catch(UnknownHostException e) processError(new Exception(Unknown Host); catch(UnresolvedAddressException e) processError(new Exception(Unable to resolve server address); catch (IOException e) processError(e); public SelectableChannel channel() return channel;public void receive() throws IOException if(remoteClosed)return;/接收数据 int oldPos = receiveBuf.position();for (int r = channel.read(receiveBuf); r 0; r = channel.read(receiveBuf) ;byte tempBuffer = new byte1024;receiveBuf.get(tempBuffer, 0, receiveBuf.position();Log.e(receive, = +new String(tempBuffer,UTF-8);/ 得到当前位置int pos = receiveBuf.position();receiveBuf.flip();/ 检查是否读了0字节,这种情况一般表示远程已经关闭了这个连接if(oldPos = pos) remoteClosed = true; return; InPacket packet = new InPacket(receiveBuf); inQueue.add(packet); adjustBuffer(pos);private void adjustBuffer(int pos) / 如果0不等于当前pos,说明至少分析了一个包 if(receiveBuf.position() 0) receiveBpact(); receiveBuf.limit(receiveBuf.capacity(); else receiveBuf.limit(receiveBuf.capacity(); receiveBuf.position(pos); public void send() throws IOException while (!isEmpty() sendBuf.clear();OutPacket packet = remove();channel.write(ByteBuffer.wrap(packet.getBody();/ 添加到重发队列packet.setTimeout(System.currentTimeMillis() + EnginConst.QQ_TIMEOUT_SEND);Log.e(debug,have sended packet - + packet.toString(); public void send(OutPacket packet) try sendBuf.clear();channel.write(ByteBuffer.wrap(packet.getBody(); Log.d(debug,have sended packet - + packet.toString(); catch (Exception e) public void send(ByteBuffer buffer) try channel.write(buffer); catch (IOException e) public void dispose() try channel.close(); catch(IOException e) public boolean isConnected() return channel != null & channel.isConnected(); public void processConnect(SelectionKey sk) throws IOException /完成SocketChannel的连接 channel.finishConnect(); while(!channel.isConnected() try Thread.sleep(300); catch (InterruptedException e) channel.finishConnect(); erestOps(SelectionKey.OP_READ); Log.e(debug,hava connected to server); public void processRead(SelectionKey sk) throws IOException receive(); public void processWrite() throws IOException if(isConnected() send(); 测试代码public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContent
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 强化训练自考专业(小学教育)试题带答案(研优卷)
- 兴业银行芜湖市鸠江区2025秋招笔试英文行测高频题含答案
- 华夏银行泉州市晋江市2025秋招笔试专业知识题专练及答案
- 招商银行宁波市宁海县2025秋招笔试创新题型专练及答案
- 2025年江苏无锡学院招聘高层次人才(长期)笔试备考题库及答案详解一套
- 民生银行长春市朝阳区2025秋招半结构化面试15问及话术
- 民生银行天津市静海区2025秋招无领导模拟题角色攻略
- 中信银行贵阳市乌当区2025秋招结构化面试15问及话术
- 光大银行大连市瓦房店市2025秋招笔试价值观测评题专练及答案
- 2025年上半年黑龙江中医药大学附属第四医院招聘工作人员考前自测高频考点模拟试题附答案详解(满分必刷)
- 超早期脑梗死的CT影像表现及诊断课件
- 拉西地平原料制药课程设计说明书
- 小学体育-小学二年级《单双脚跳》教学设计学情分析教材分析课后反思
- 居室环境的清洁与消毒
- ××领导班子及成员分析研判报告
- GB/T 9124.1-2019钢制管法兰第1部分:PN系列
- GB/T 2518-2008连续热镀锌钢板及钢带
- Frenchay构音障碍评定
- 教育学原理课后答案主编项贤明
- 建筑装饰施工技术-轻质隔墙工程施工课件(-)
- 语言领域核心经验《学前儿童语言学习与发展核心经验》
评论
0/150
提交评论