当前位置:   article > 正文

[置顶] android socket 聊天实现与调试

废话不多说,附主要的client类

网上很多基于Socket的聊天实现都是不完整的。。。

结合自己的经验给大家分享一下,完整代码可以在GitHub里获取https://github.com/zz7zz7zz/android-socket-client

 

1.废话不多说,附主要的Client类

 

  1. package com.boyaa.push.lib.service;
  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.io.OutputStream;
  5. import java.net.InetSocketAddress;
  6. import java.net.Socket;
  7. import java.net.SocketException;
  8. import java.util.Iterator;
  9. import java.util.concurrent.LinkedBlockingQueue;
  10. import android.content.Context;
  11. import android.util.Log;
  12. import com.boyaa.push.lib.util.NetworkUtil;
  13. /**
  14. *
  15. * @author Administrator
  16. *
  17. */
  18. public class Client {
  19. private final int STATE_OPEN=1;//socket打开
  20. private final int STATE_CLOSE=1<<1;//socket关闭
  21. private final int STATE_CONNECT_START=1<<2;//开始连接server
  22. private final int STATE_CONNECT_SUCCESS=1<<3;//连接成功
  23. private final int STATE_CONNECT_FAILED=1<<4;//连接失败
  24. private final int STATE_CONNECT_WAIT=1<<5;//等待连接
  25. private String IP="192.168.1.100";
  26. private int PORT=60000;
  27. private int state=STATE_CONNECT_START;
  28. private Socket socket=null;
  29. private OutputStream outStream=null;
  30. private InputStream inStream=null;
  31. private Thread conn=null;
  32. private Thread send=null;
  33. private Thread rec=null;
  34. private Context context;
  35. private ISocketResponse respListener;
  36. private LinkedBlockingQueue<Packet> requestQueen=new LinkedBlockingQueue<Packet>();
  37. private final Object lock=new Object();
  38. public int send(Packet in)
  39. {
  40. requestQueen.add(in);
  41. synchronized (lock)
  42. {
  43. lock.notifyAll();
  44. }
  45. return in.getId();
  46. }
  47. public void cancel(int reqId)
  48. {
  49. Iterator<Packet> mIterator=requestQueen.iterator();
  50. while (mIterator.hasNext())
  51. {
  52. Packet packet=mIterator.next();
  53. if(packet.getId()==reqId)
  54. {
  55. mIterator.remove();
  56. }
  57. }
  58. }
  59. public Client(Context context,ISocketResponse respListener)
  60. {
  61. this.context=context;
  62. this.respListener=respListener;
  63. }
  64. public boolean isNeedConn()
  65. {
  66. return !((state==STATE_CONNECT_SUCCESS)&&(null!=send&&send.isAlive())&&(null!=rec&&rec.isAlive()));
  67. }
  68. public void open()
  69. {
  70. reconn();
  71. }
  72. public void open(String host,int port)
  73. {
  74. this.IP=host;
  75. this.PORT=port;
  76. reconn();
  77. }
  78. private long lastConnTime=0;
  79. public synchronized void reconn()
  80. {
  81. if(System.currentTimeMillis()-lastConnTime<2000)
  82. {
  83. return;
  84. }
  85. lastConnTime=System.currentTimeMillis();
  86. close();
  87. state=STATE_OPEN;
  88. conn=new Thread(new Conn());
  89. conn.start();
  90. }
  91. public synchronized void close()
  92. {
  93. if(state!=STATE_CLOSE)
  94. {
  95. try {
  96. if(null!=socket)
  97. {
  98. socket.close();
  99. }
  100. } catch (Exception e) {
  101. e.printStackTrace();
  102. }finally{
  103. socket=null;
  104. }
  105. try {
  106. if(null!=outStream)
  107. {
  108. outStream.close();
  109. }
  110. } catch (Exception e) {
  111. e.printStackTrace();
  112. }finally{
  113. outStream=null;
  114. }
  115. try {
  116. if(null!=inStream)
  117. {
  118. inStream.close();
  119. }
  120. } catch (Exception e) {
  121. e.printStackTrace();
  122. }finally{
  123. inStream=null;
  124. }
  125. try {
  126. if(null!=conn&&conn.isAlive())
  127. {
  128. conn.interrupt();
  129. }
  130. } catch (Exception e) {
  131. e.printStackTrace();
  132. }finally{
  133. conn=null;
  134. }
  135. try {
  136. if(null!=send&&send.isAlive())
  137. {
  138. send.interrupt();
  139. }
  140. } catch (Exception e) {
  141. e.printStackTrace();
  142. }finally{
  143. send=null;
  144. }
  145. try {
  146. if(null!=rec&&rec.isAlive())
  147. {
  148. rec.interrupt();
  149. }
  150. } catch (Exception e) {
  151. e.printStackTrace();
  152. }finally{
  153. rec=null;
  154. }
  155. state=STATE_CLOSE;
  156. }
  157. requestQueen.clear();
  158. }
  159. private class Conn implements Runnable
  160. {
  161. public void run() {
  162. while(state!=STATE_CLOSE)
  163. {
  164. try {
  165. state=STATE_CONNECT_START;
  166. socket=new Socket();
  167. socket.connect(new InetSocketAddress(IP, PORT), 15*1000);
  168. state=STATE_CONNECT_SUCCESS;
  169. } catch (Exception e) {
  170. e.printStackTrace();
  171. state=STATE_CONNECT_FAILED;
  172. }
  173. if(state==STATE_CONNECT_SUCCESS)
  174. {
  175. try {
  176. outStream=socket.getOutputStream();
  177. inStream=socket.getInputStream();
  178. } catch (IOException e) {
  179. e.printStackTrace();
  180. }
  181. send=new Thread(new Send());
  182. rec=new Thread(new Rec());
  183. send.start();
  184. rec.start();
  185. break;
  186. }
  187. else
  188. {
  189. state=STATE_CONNECT_WAIT;
  190. //如果有网络没有连接上,则定时取连接,没有网络则直接退出
  191. if(NetworkUtil.isNetworkAvailable(context))
  192. {
  193. try {
  194. Thread.sleep(15*1000);
  195. } catch (InterruptedException e) {
  196. e.printStackTrace();
  197. break;
  198. }
  199. }
  200. else
  201. {
  202. break;
  203. }
  204. }
  205. }
  206. }
  207. }
  208. private class Send implements Runnable
  209. {
  210. public void run() {
  211. try {
  212. while(state!=STATE_CLOSE&&state==STATE_CONNECT_SUCCESS&&null!=outStream)
  213. {
  214. Packet item;
  215. while(null!=(item=requestQueen.poll()))
  216. {
  217. outStream.write(item.getPacket());
  218. outStream.flush();
  219. item=null;
  220. }
  221. synchronized (lock)
  222. {
  223. lock.wait();
  224. }
  225. }
  226. }catch(SocketException e1)
  227. {
  228. e1.printStackTrace();//发送的时候出现异常,说明socket被关闭了(服务器关闭)java.net.SocketException: sendto failed: EPIPE (Broken pipe)
  229. reconn();
  230. }
  231. catch (Exception e) {
  232. e.printStackTrace();
  233. }
  234. }
  235. }
  236. private class Rec implements Runnable
  237. {
  238. public void run() {
  239. try {
  240. while(state!=STATE_CLOSE&&state==STATE_CONNECT_SUCCESS&&null!=inStream)
  241. {
  242. byte[] bodyBytes=new byte[5];
  243. int offset=0;
  244. int length=5;
  245. int read=0;
  246. while((read=inStream.read(bodyBytes, offset, length))>0)
  247. {
  248. if(length-read==0)
  249. {
  250. if(null!=respListener)
  251. {
  252. respListener.onSocketResponse(new String(bodyBytes));
  253. }
  254. offset=0;
  255. length=5;
  256. read=0;
  257. continue;
  258. }
  259. offset+=read;
  260. length=5-offset;
  261. }
  262. reconn();//走到这一步,说明服务器socket断了
  263. break;
  264. }
  265. }
  266. catch(SocketException e1)
  267. {
  268. e1.printStackTrace();//客户端主动socket.close()会调用这里 java.net.SocketException: Socket closed
  269. }
  270. catch (Exception e2) {
  271. e2.printStackTrace();
  272. }
  273. }
  274. }
  275. }
 
 

 

2.使用SocketTool工具进行调试

a.创建Server.点击TCP Server ,点击创建,输入端口号,点击确定(同时要点击启动监听)。

b.在android客户端输入IP和端口,点击打开或者重连,socketTool便可以看见你连上的Client了

c.在客户端输入要发送的文字,点击发送,在socketTool便可以看到你往server里发送的数据了,

在socketTool里输入要往客户端发送的内容,点击发送,便可在手机客户端里看到Server往client发送的数据了

这样就可以Client-Server之间进行数据对发了。

 

 

 

 

 

邮箱:zz7zz7zz@163.com

微博http://weibo.com/u/3209971935
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/594975
推荐阅读
相关标签
  

闽ICP备14008679号