实现android socket 聊天与调试
2013-07-21 13:31:47 来源:WEB开发网核心提示: 主要的Client类package com.boyaa.push.lib.service;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.InetSocketAddres
主要的Client类
package com.boyaa.push.lib.service; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketException; import java.util.Iterator; import java.util.concurrent.LinkedBlockingQueue; import android.content.Context; import android.util.Log; import com.boyaa.push.lib.util.NetworkUtil; /** * * @author Administrator * */ public class Client { private final int STATE_OPEN=1;//socket打开 private final int STATE_CLOSE=1<<1;//socket关闭 private final int STATE_CONNECT_START=1<<2;//开始连接server private final int STATE_CONNECT_SUCCESS=1<<3;//连接成功 private final int STATE_CONNECT_FAILED=1<<4;//连接失败 private final int STATE_CONNECT_WAIT=1<<5;//等待连接 private String IP="192.168.1.100"; private int PORT=60000; private int state=STATE_CONNECT_START; private Socket socket=null; private OutputStream outStream=null; private InputStream inStream=null; private Thread conn=null; private Thread send=null; private Thread rec=null; private Context context; private ISocketResponse respListener; private LinkedBlockingQueue<Packet> requestQueen=new LinkedBlockingQueue<Packet>(); private final Object lock=new Object(); public int send(Packet in) { requestQueen.add(in); synchronized (lock) { lock.notifyAll(); } return in.getId(); } public void cancel(int reqId) { Iterator<Packet> mIterator=requestQueen.iterator(); while (mIterator.hasNext()) { Packet packet=mIterator.next(); if(packet.getId()==reqId) { mIterator.remove(); } } } public Client(Context context,ISocketResponse respListener) { this.context=context; this.respListener=respListener; } public boolean isNeedConn() { return !((state==STATE_CONNECT_SUCCESS)&&(null!=send&&send.isAlive())&&(null!=rec&&rec.isAlive())); } public void open() { reconn(); } public void open(String host,int port) { this.IP=host; this.PORT=port; reconn(); } private long lastConnTime=0; public synchronized void reconn() { if(System.currentTimeMillis()-lastConnTime<2000) { return; } lastConnTime=System.currentTimeMillis(); close(); state=STATE_OPEN; conn=new Thread(new Conn()); conn.start(); } public synchronized void close() { if(state!=STATE_CLOSE) { try { if(null!=socket) { socket.close(); } } catch (Exception e) { e.printStackTrace(); }finally{ socket=null; } try { if(null!=outStream) { outStream.close(); } } catch (Exception e) { e.printStackTrace(); }finally{ outStream=null; } try { if(null!=inStream) { inStream.close(); } } catch (Exception e) { e.printStackTrace(); }finally{ inStream=null; } try { if(null!=conn&&conn.isAlive()) { conn.interrupt(); } } catch (Exception e) { e.printStackTrace(); }finally{ conn=null; } try { if(null!=send&&send.isAlive()) { send.interrupt(); } } catch (Exception e) { e.printStackTrace(); }finally{ send=null; } try { if(null!=rec&&rec.isAlive()) { rec.interrupt(); } } catch (Exception e) { e.printStackTrace(); }finally{ rec=null; } state=STATE_CLOSE; } requestQueen.clear(); } private class Conn implements Runnable { public void run() { while(state!=STATE_CLOSE) { try { state=STATE_CONNECT_START; socket=new Socket(); socket.connect(new InetSocketAddress(IP, PORT), 15*1000); state=STATE_CONNECT_SUCCESS; } catch (Exception e) { e.printStackTrace(); state=STATE_CONNECT_FAILED; } if(state==STATE_CONNECT_SUCCESS) { try { outStream=socket.getOutputStream(); inStream=socket.getInputStream(); } catch (IOException e) { e.printStackTrace(); } send=new Thread(new Send()); rec=new Thread(new Rec()); send.start(); rec.start(); break; } else { state=STATE_CONNECT_WAIT; //如果有网络没有连接上,则定时取连接,没有网络则直接退出 if(NetworkUtil.isNetworkAvailable(context)) { try { Thread.sleep(15*1000); } catch (InterruptedException e) { e.printStackTrace(); break; } } else { break; } } } } } private class Send implements Runnable { public void run() { try { while(state!=STATE_CLOSE&&state==STATE_CONNECT_SUCCESS&&null!=outStream) { Packet item; while(null!=(item=requestQueen.poll())) { outStream.write(item.getPacket()); outStream.flush(); item=null; } synchronized (lock) { lock.wait(); } } }catch(SocketException e1) { e1.printStackTrace();//发送的时候出现异常,说明socket被关闭了(服务器关闭)java.net.SocketException: sendto failed: EPIPE (Broken pipe) reconn(); } catch (Exception e) { e.printStackTrace(); } } } private class Rec implements Runnable { public void run() { try { while(state!=STATE_CLOSE&&state==STATE_CONNECT_SUCCESS&&null!=inStream) { byte[] bodyBytes=new byte[5]; int offset=0; int length=5; int read=0; while((read=inStream.read(bodyBytes, offset, length))>0) { if(length-read==0) { if(null!=respListener) { respListener.onSocketResponse(new String(bodyBytes)); } offset=0; length=5; read=0; continue; } offset+=read; length=5-offset; } reconn();//走到这一步,说明服务器socket断了 break; } } catch(SocketException e1) { e1.printStackTrace();//客户端主动socket.close()会调用这里 java.net.SocketException: Socket closed } catch (Exception e2) { e2.printStackTrace(); } } } }
- ››Android 当修改一些代码时,使用什么编译命令可以最...
- ››Android 如何添加一个apk使模拟器和真机都编译进去...
- ››Android 修改Camera拍照的默认保存路径
- ››Android 如何修改默认输入法
- ››android开发中finish()和System.exit(0)的区别
- ››Android手势识别简单封装类
- ››android中查看项目数字证书的两种方法
- ››Android中获取IMEI码的办法
- ››android 相机报错 setParameters failed
- ››Android重启运用程序的代码
- ››Android为ListView的Item设置不同的布局
- ››android bitmap与base64字符串的互相转换
赞助商链接