Android使用NIO开发客户端
来源:互联网 发布:网络营销策划是it吗 编辑:程序博客网 时间:2024/06/05 00:41
SocketUtil.java
package com.lee.ademo.net;import java.io.ByteArrayOutputStream;import java.io.EOFException;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.SocketChannel;import java.util.Iterator;import java.util.Set;import com.lee.ademo.base.MLog;public class SocketUtil extends Thread {protected Selector selector = null;protected SocketChannel client = null;protected static final int CONNECT_TIMEOUT = 10000;protected static final int READ_TIMEOUT = 10000;protected static final int RECONNECT_TIME = 120000;protected static final int RECONNECT_TIME_SECOND = RECONNECT_TIME / 1000;protected final byte CONNECT = 1;protected final byte RUNNING = 2;protected byte STATE = CONNECT;protected boolean onWork;// 是否工作状态static {java.lang.System.setProperty("java.net.preferIPv6Addresses", "false");};private static String ip = "127.0.0.1";private static int port = 9527;private ConnectListener connectListener;public static enum ENUM_CONNECT {STATUS_OK, STATUS_FAIL};public SocketUtil(String ip, int port) {SocketUtil.ip = ip;SocketUtil.port = port;onWork = true;}public boolean isReady() {return STATE == RUNNING;}@Overridepublic void run() {// TODO Auto-generated method stubwhile (onWork) {switch (STATE) {case CONNECT:connect();break;case RUNNING:running();break;default:break;}}}private synchronized void running() {SelectionKey key = null;try {while (selector.select() > 0) {Set<SelectionKey> keys = selector.selectedKeys();Iterator<SelectionKey> iterator = keys.iterator();while (iterator.hasNext()) {key = iterator.next();iterator.remove();byte[] data = readBuf(key);if (data != null)MLog.makeText(new String(data));}}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();closeKey(key);}}private final byte[] readBuf(SelectionKey selectionKey) throws IOException {if (selectionKey.isReadable()) {SocketChannel client = (SocketChannel) selectionKey.channel();// 如果缓冲区过小的话那么信息流会分成多次接收ByteArrayOutputStream bos = (ByteArrayOutputStream) selectionKey.attachment();ByteBuffer buffer = ByteBuffer.allocate(10240);// 10kb缓存int actual = 0;while ((actual = client.read(buffer)) > 0) {buffer.flip();int limit = buffer.limit();byte b[] = new byte[limit];buffer.get(b);bos.write(b);buffer.clear();// 清空}if (actual < 0) {// 出现异常selectionKey.cancel();client.socket().close();client.close();throw new EOFException("Read EOF");}bos.flush();byte[] data = bos.toByteArray();bos.reset();return data;}return null;}public final boolean writeBuf(byte[] data) throws Exception {if (client.isConnected()) {ByteBuffer buffer = ByteBuffer.wrap(data);int size = buffer.remaining();// 此处需加中途断开逻辑,下次再继续发送数据包int actually = client.write(buffer);if (actually == size)return true;}return false;}/** * 唤起连接线程重新连接 */protected synchronized void reconnect() {notify();}private synchronized void connect() {try {selector = Selector.open();InetSocketAddress isa = new InetSocketAddress(ip, port);client = SocketChannel.open();// 设置连超时client.socket().connect(isa, CONNECT_TIMEOUT);// 设置读超时client.socket().setSoTimeout(READ_TIMEOUT);client.configureBlocking(false);client.register(selector, SelectionKey.OP_READ,new ByteArrayOutputStream());if (client.isConnected()) {// 连接成功开始监听服务端消息// 发送一个验证数据包到服务器进行验证STATE = RUNNING;if (connectListener != null)connectListener.connect(ENUM_CONNECT.STATUS_OK);MLog.makeText("连接成功");} else {// 关闭通道过60S重新开始连接if (connectListener != null)connectListener.connect(ENUM_CONNECT.STATUS_FAIL);StringBuffer buffer = new StringBuffer("服务器连接失败");buffer.append(RECONNECT_TIME_SECOND);buffer.append("秒后再尝试连接");MLog.makeText(buffer);close();// 关闭通道Wait(RECONNECT_TIME);}} catch (Exception e) {// TODO Auto-generated catch block// 有异常关闭通道过60S重新开始连接e.printStackTrace();StringBuffer buffer = new StringBuffer("连接出错啦!");buffer.append(RECONNECT_TIME_SECOND);buffer.append("秒后再尝试连接");MLog.makeText(buffer);close();// 关闭通道Wait(RECONNECT_TIME);}}public void close() {STATE = CONNECT;try {if (client != null) {client.socket().close();client.close();client = null;}if (selector != null) {selector.close();selector = null;}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}private void closeKey(SelectionKey key) {if (key != null) {key.cancel();try {key.channel().close();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();StringBuffer buffer = new StringBuffer("连接断开啦!");buffer.append(RECONNECT_TIME_SECOND);buffer.append("秒后再尝试连接");MLog.makeText(buffer);Wait(RECONNECT_TIME);}}close();}private void Wait(long millis) {try {wait(millis);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public ConnectListener getConnectListener() {return connectListener;}public void setConnectListener(ConnectListener connectListener) {this.connectListener = connectListener;}public interface ConnectListener {public void connect(ENUM_CONNECT STATUS);}}
IT十万为什么 » Android使用NIO开发客户端
0 0
- Android使用NIO开发客户端
- Android使用NIO开发客户端
- Android 使用Mina的Nio实现客户端服务器通信
- Java NIO客户端开发问题
- [Android开发] Android客户端使用socket通信
- [Android开发] Android客户端使用HTTP通信
- Android模拟器上使用NIO编写客户端中,使用select超时,立马返回0的问题
- java nio Selector的使用-客户端
- java nio Selector的使用-客户端
- java nio Selector的使用-客户端
- NIO客户端
- android ftp客户端开发
- 客户端开发规范-Android
- Android 新闻客户端开发
- android 新闻客户端开发
- android 客户端开发
- Android 客户端开发
- Android网站客户端开发
- 手机连接本地apache服务器
- 第十七周项目3:胖子伤不起-结构体
- qt5 判别操作系统
- WebRTC 点对点视频通话系统
- openwrt试用记录
- Android使用NIO开发客户端
- 常用生僻linux命令
- 《老罗的Android之旅》阅读笔记——Launcher和Zygote的启动过程
- 总结下网上的JS控制密码框获取焦点时文字消失,失去焦点时文字出现的方法
- java 继承总结
- servlet学习笔记
- Ceph OSD因为xfs fadvise(DONTNEED)问题无法启动
- mvc ajaxbeginform oncussful
- linux中源码编译安装git