zoukankan      html  css  js  c++  java
  • 安卓Socket处理

    初学Android Socket 部分代码参考于网络,结合项目测试后修改总结,在此记录。




    1
    /** 2 * <p> 3 * socket连接服务 4 */ 5 public class SocketService extends Service { 6 7 private static final String TAG = "SocketService"; 8 9 /*socket*/ 10 private Socket socket; 11 /*连接线程*/ 12 private Thread connectThread; 13 private Timer timer = new Timer(); 14 15 16 /* 读写输入流*/ 17 private InputStream inputStream; 18 private DataInputStream dis; 19 20 /*读接收数据线程*/ 21 private Thread readThread; 22 /*接收数据长度*/ 23 private int rcvLength; 24 /*接收数据*/ 25 private String rcvMsg; 26 /* 读取保存进数组*/ 27 byte buff[] = new byte[1024 * 1024 * 2]; 28 29 private OutputStream outputStream; 30 31 32 private SocketBinder sockerBinder = new SocketBinder(); 33 private String ip;//IP地址,这里最好单独建立一个存放数据类,用来存放网络通讯使用到的数据 34 private String port;//端口号 35 private TimerTask task; 36 37 /*默认重连*/ 38 private boolean isReConnect = true; 39 40 41 /* 线程状态,安全结束线程*/ 42 private boolean threadStatus = false; 43 44 private Handler handler = new Handler(Looper.getMainLooper()); 45 46 47 @Override 48 public IBinder onBind(Intent intent) { 49 return sockerBinder; 50 } 51 52 53 public class SocketBinder extends Binder {//通过ServiceConnection获取,后面会讲解 54 /*返回SocketService 在需要的地方可以通过ServiceConnection获取到SocketService */ 55 public SocketService getService() { 56 return SocketService.this; 57 } 58 } 59 60 @Override 61 public void onCreate() { 62 super.onCreate(); 63 } 64 65 66 @Override 67 public int onStartCommand(Intent intent, int flags, int startId) { 68 69 /*拿到传递过来的ip和端口号*/ 70 ip = Constants.INTENT_IP; 71 port = Constants.INTENT_PORT; 72 73 Log.e(TAG, "000" + DeviceUuidFactory.getUuid()); 74 75 /*初始化socket*/ 76 initSocket(); 77 78 return super.onStartCommand(intent, flags, startId); 79 } 80 81 82 /*初始化socket*/ 83 private void initSocket() { 84 85 if (socket == null && connectThread == null) { 86 87 //启动读取数据 88 connectThread = new Thread(new Runnable() { 89 @Override 90 public void run() { 91 socket = new Socket(); 92 try { 93 /*超时时间为20秒*/ 94 socket.connect(new InetSocketAddress(ip, Integer.valueOf(port)), 20000); 95 /*连接成功的话 发送心跳包*/ 96 if (socket.isConnected()) { 97 98 inputStream = socket.getInputStream(); 99 dis = new DataInputStream(inputStream); 100 101 if (inputStream != null) { 102 /* 开启读写线程 */ 103 threadStatus = true; 104 readThread = new ReadThread(); 105 readThread.start(); 106 } 107 108 /*因为Toast是要运行在主线程的 这里是子线程 所以需要到主线程哪里去显示toast*/ 109 // toastMsg("socket已连接111111111"); 110 111 /*发送心跳数据*/ 112 sendBeatData(); 113 } 114 115 } catch (IOException e) { 116 e.printStackTrace(); 117 if (e instanceof SocketTimeoutException) { 118 toastMsg("连接超时,正在重连"); 119 releaseSocket(); 120 } else if (e instanceof NoRouteToHostException) { 121 toastMsg("该地址不存在,请检查"); 122 stopSelf(); 123 } else if (e instanceof ConnectException) { 124 toastMsg("连接异常或被拒绝,请检查"); 125 stopSelf(); 126 } 127 } 128 } 129 }); 130 /*启动连接线程*/ 131 connectThread.start(); 132 } 133 } 134 135 /*因为Toast是要运行在主线程的 所以需要到主线程哪里去显示toast*/ 136 private void toastMsg(final String msg) { 137 138 handler.post(new Runnable() { 139 @Override 140 public void run() { 141 Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show(); 142 } 143 }); 144 } 145 146 147 /** 148 * @param order 149 * @param msg//测试时使用 150 */ 151 /*发送数据*/ 152 public void sendOrder(final String order, final String msg) { 153 if (socket != null && socket.isConnected()) { 154 /*发送指令*/ 155 new Thread(new Runnable() { 156 @Override 157 public void run() { 158 try { 159 Log.e("准备回复消息:", msg); 160 outputStream = socket.getOutputStream(); 161 if (outputStream != null) { 162 outputStream.write(order.getBytes("gbk")); 163 outputStream.flush(); 164 Log.e("消息发送成功:", order); 165 } 166 } catch (IOException e) { 167 e.printStackTrace(); 168 //releaseSocket(); 169 Log.e("消息回复异常", msg); 170 } 171 } 172 }).start(); 173 } else { 174 Log.e(TAG, "socket连接错误,请重试"); 175 releaseSocket(); 176 } 177 } 178 179 180 /** 181 * 发送连接状态消息 182 * 183 * @param constants 184 */ 185 private void sendEventMsg(String constants) { 186 EventMsg msg = new EventMsg(); 187 msg.setTag(constants); 188 EventBus.getDefault().post(msg); 189 } 190 191 /** 192 * 发送连接状态消息 193 * 194 * @param constants 195 */ 196 private void sendEventMsg(String constants, String rcvMsg) { 197 EventMsg msg = new EventMsg();//EventMsg的使用自行百度 198 msg.setTag(constants); 199 msg.setMsg(rcvMsg); 200 EventBus.getDefault().post(msg); 201 } 202 203 204 /** 205 * 接收数据 206 */ 207 private class ReadThread extends Thread { 208 @TargetApi(Build.VERSION_CODES.KITKAT) 209 @Override 210 public void run() { 211 super.run(); 212 //判断进程是否在运行,更安全的结束进程 213 try { 214 while (!socket.isClosed() && threadStatus && ((rcvLength = dis.read(buff)) != -1)) { 215 216 Log.e(TAG, "buff:" + buff); 217 218 if (rcvLength > 0) { 219 rcvMsg = new String(buff, 0, rcvLength, "GBK"); 220 toastMsg("收到服务器消息"); 221 //接收到数据 222 handleData(rcvMsg);//处理数据并回复服务器 223 } 224 } 225 } catch (Exception e) { 226 toastMsg("接收总控数据异常"); 227 } 228 229 } 230 } 231 232 233 /*定时发送数据*/ 234 private void sendBeatData() { 235 if (timer == null) { 236 timer = new Timer(); 237 } 238 239 if (task == null) { 240 task = new TimerTask() { 241 @Override 242 public void run() { 243 try { 244 outputStream = socket.getOutputStream(); 245 /*这里的编码方式根据需求去改*/ 246 outputStream.write("这是一条心跳数据".getBytes("gbk")); 247 outputStream.flush(); 248 /*发送连接成功的消息*/ 249 //这里可以建立一条消息发送到Activity处理界面相关 250 } catch (Exception e) { 251 /*发送失败说明socket断开了或者出现了其他错误*/ 252 toastMsg("连接断开,正在重连"); 253 /*发送连接失败的消息*/ 254 sendEventMsg(Constants.CONNET_FAIL, ""); 255 /*重连*/ 256 releaseSocket(); 257 e.printStackTrace(); 258 } 259 } 260 }; 261 } 262 263 timer.schedule(task, 0, 60000);//心跳每隔60000毫秒发送一次,60s 264 } 265 266 267 /*释放资源*/ 268 private void releaseSocket() { 269 270 if (task != null) { 271 task.cancel(); 272 task = null; 273 } 274 if (timer != null) { 275 timer.purge(); 276 timer.cancel(); 277 timer = null; 278 } 279 280 if (outputStream != null) { 281 try { 282 outputStream.close(); 283 284 } catch (IOException e) { 285 e.printStackTrace(); 286 } 287 outputStream = null; 288 } 289 290 if (socket != null) { 291 try { 292 socket.close(); 293 294 } catch (IOException e) { 295 } 296 socket = null; 297 } 298 299 if (connectThread != null) { 300 connectThread = null; 301 } 302 303 if (readThread != null) { 304 readThread = null; 305 } 306 307 /*重新初始化socket*/ 308 if (isReConnect) { 309 initSocket(); 310 } 311 312 } 313 314 315 /** 316 * 服务器消息回复 317 * 318 * @param msg 319 * @param 320 */ 321 @TargetApi(Build.VERSION_CODES.KITKAT) 322 public void handleData(String msg) throws IOException { 323 sendOrder("确认收到消息", msg); 324 } 325 326 327 @Override 328 public void onDestroy() { 329 super.onDestroy(); 330 Log.i("SocketService", "onDestroy"); 331 isReConnect = false; 332 threadStatus = false; 333 releaseSocket(); 334 } 335 }

    IBinder 使用方法
     1  ServiceConnection serviceConnection = new ServiceConnection() {
     2                              @Override
     3                              public void onServiceConnected(ComponentName name, IBinder service) {
     4                                  SocketService.SocketBinder socketBinder = (SocketService.SocketBinder) service;
     5                                  socketBinder.getService().
     6                              }
     7  
     8                              @Override
     9                              public void onServiceDisconnected(ComponentName name) {
    10 
    11                             }
    12                         };
    
    
    
     


  • 相关阅读:
    Verilog非阻塞赋值的仿真/综合问题 (Nonblocking Assignments in Verilog Synthesis)上
    异步FIFO结构及FPGA设计 跨时钟域设计
    FPGA管脚分配需要考虑的因素
    An Introduction to Delta Sigma Converters (DeltaSigma转换器 上篇)
    An Introduction to Delta Sigma Converters (DeltaSigma转换器 下篇)
    中国通信简史 (下)
    谈谈德国大学的电子专业
    中国通信简史 (上)
    Verilog学习笔记
    Verilog非阻塞赋值的仿真/综合问题(Nonblocking Assignments in Verilog Synthesis) 下
  • 原文地址:https://www.cnblogs.com/bbqopdd/p/10761639.html
Copyright © 2011-2022 走看看