通過socket獲取字節流處理時最初使用的是BufferedReader和PrintWriter 這種方式在解析字符串時是比較方便的 但是在處理字節時不夠方便最終還是回歸到InputStream和OutputStream方式 不使用緩存直接使用字節流操作,一次傳輸的字節數據在300字節以內,目前沒有測試差距會有多大。
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; import java.util.Arrays; import android.content.Context; import android.content.SharedPreferences; import android.os.Handler; import android.os.Message; import android.util.Log; public class SocThread extends Thread { private String ip = "10.0.0.113"; private int port = 6666; private String TAG = "socket thread"; private int timeout = 10000; int maxsize = 256; public Socket client = null; PrintWriter out; BufferedReader in; public boolean isRun = true; Handler inHandler; Handler outHandler; Context ctx; private String TAG1 = "===Send==="; SharedPreferences sp; public SocThread(Handler handlerin, Handler handlerout, Context context) { inHandler = handlerin; outHandler = handlerout; ctx = context; MyLog.i(TAG, "創建線程socket"); } /** * 連接socket服務器 */ public void conn() { try { initdate(); Log.i(TAG, "連接中……"); client = new Socket(ip, port); client.setSoTimeout(timeout);// 設置阻塞時間 MyLog.i(TAG, "連接成功"); in = new BufferedReader(new InputStreamReader( client.getInputStream())); out = new PrintWriter(new BufferedWriter(new OutputStreamWriter( client.getOutputStream())), true); MyLog.i(TAG, "輸入輸出流獲取成功"); } catch (UnknownHostException e) { MyLog.i(TAG, "連接錯誤UnknownHostException 重新獲取"); e.printStackTrace(); conn(); } catch (IOException e) { MyLog.i(TAG, "連接服務器io錯誤"); e.printStackTrace(); } catch (Exception e) { MyLog.i(TAG, "連接服務器錯誤Exception" + e.getMessage()); e.printStackTrace(); } } public void initdate() { sp = ctx.getSharedPreferences("SP", ctx.MODE_PRIVATE); ip = sp.getString("ipstr", ip); port = Integer.parseInt(sp.getString("port", String.valueOf(port))); MyLog.i(TAG, "獲取到ip端口:" + ip + ";" + port); } /** * 實時接受數據 */ @Override public void run() { MyLog.i(TAG, "線程socket開始運行"); conn(); MyLog.i(TAG, "1.run開始"); String line = ""; while (isRun) { try { if (client != null) { MyLog.i(TAG, "2.檢測數據"); // 以下是按行直接讀取字符流 while ((line = in.readLine()) != null) { MyLog.i(TAG, "3.getdata" + line + " len=" + line.length()); MyLog.i(TAG, "4.start set Message"); Message msg = inHandler.obtainMessage(); msg.obj = line; inHandler.sendMessage(msg);// 結果返回給UI處理 MyLog.i(TAG1, "5.send to handler"); } } else { MyLog.i(TAG, "沒有可用連接"); conn(); } } catch (Exception e) { MyLog.i(TAG, "數據接收錯誤" + e.getMessage()); e.printStackTrace(); } } } /** * 發送數據 * * @param mess */ public void Send(String mess) { try { if (client != null) { MyLog.i(TAG1, "發送" + mess + "至" + client.getInetAddress().getHostAddress() + ":" + String.valueOf(client.getPort())); out.println(mess);//按字符流發送 out.flush(); MyLog.i(TAG1, "發送成功"); Message msg = outHandler.obtainMessage(); msg.obj = mess; msg.what = 1; outHandler.sendMessage(msg);// 結果返回給UI處理 } else { MyLog.i(TAG, "client 不存在"); Message msg = outHandler.obtainMessage(); msg.obj = mess; msg.what = 0; outHandler.sendMessage(msg);// 結果返回給UI處理 MyLog.i(TAG, "連接不存在重新連接"); conn(); } } catch (Exception e) { MyLog.i(TAG1, "send error"); e.printStackTrace(); } finally { MyLog.i(TAG1, "發送完畢"); } } /** * 關閉連接 */ public void close() { try { if (client != null) { MyLog.i(TAG, "close in"); in.close(); MyLog.i(TAG, "close out"); out.close(); MyLog.i(TAG, "close client"); client.close(); } } catch (Exception e) { MyLog.i(TAG, "close err"); e.printStackTrace(); } } }
原始字節流讀取處理如下
package com.example.testsocket; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; import android.content.Context; import android.content.SharedPreferences; import android.os.Handler; import android.os.Message; import android.util.Log; public class SocThread extends Thread { private String ip = "10.0.0.113"; private int port = 6666; private String TAG = "socket thread"; private int timeout = 10000; private int maxsize = 256;// 默認接受大小 public Socket client = null; // PrintWriter out; // BufferedReader in; OutputStream out; InputStream in; public boolean isRun = true; Handler inHandler; Handler outHandler; Context ctx; private String TAG1 = "===Send==="; SharedPreferences sp; public SocThread(Handler handlerin, Handler handlerout, Context context) { inHandler = handlerin; outHandler = handlerout; ctx = context; MyLog.i(TAG, "創建線程socket"); } /** * 連接socket服務器 */ public void conn() { try { initdate(); Log.i(TAG, "連接中……"); client = new Socket(ip, port); client.setSoTimeout(timeout);// 設置阻塞時間 MyLog.i(TAG, "連接成功"); in = client.getInputStream(); out = client.getOutputStream(); // 以下在字符流時比較好用 // in = new BufferedReader(new InputStreamReader( // client.getInputStream())); // out = new PrintWriter(new BufferedWriter(new OutputStreamWriter( // client.getOutputStream())), true); MyLog.i(TAG, "輸入輸出流獲取成功"); } catch (UnknownHostException e) { MyLog.i(TAG, "連接錯誤UnknownHostException 重新獲取"); e.printStackTrace(); conn(); } catch (IOException e) { MyLog.i(TAG, "連接服務器io錯誤"); e.printStackTrace(); } catch (Exception e) { MyLog.i(TAG, "連接服務器錯誤Exception" + e.getMessage()); e.printStackTrace(); } } public void initdate() { sp = ctx.getSharedPreferences("SP", ctx.MODE_PRIVATE); ip = sp.getString("ipstr", ip); port = Integer.parseInt(sp.getString("port", String.valueOf(port))); MyLog.i(TAG, "獲取到ip端口:" + ip + ";" + port); } /** * 實時接受數據 */ @Override public void run() { MyLog.i(TAG, "線程socket開始運行"); conn(); MyLog.i(TAG, "1.run開始"); String line = ""; while (isRun) { try { if (client != null) { MyLog.i(TAG, "2.檢測數據"); byte[] temp = new byte[maxsize];// 默認最帶為256 int size = 0; while ((size = in.read(temp)) > 0) { // -1表示文件結尾 byte[] res = new byte[size];// 默認最帶為256 MyLog.i(TAG, "4.start set Message 字節讀取"); System.arraycopy(temp, 0, res, 0, size); for (int i = 0; i < size; i++) { line += res[i] + " "; } MyLog.i(TAG, "3.getdata " + line + " size=" + size); MyLog.i(TAG, "4.start set Message"); Message msg = inHandler.obtainMessage(); msg.obj = line; inHandler.sendMessage(msg);// 結果返回給UI處理 MyLog.i(TAG1, "5.send to handler"); } } else { MyLog.i(TAG, "沒有可用連接"); conn(); } } catch (Exception e) { MyLog.i(TAG, "數據接收錯誤" + e.getMessage()); e.printStackTrace(); } } } /** * 發送數據 * * @param mess */ public void Send(byte[] mess) { try { if (client != null) { MyLog.i(TAG1, "發送" + mess + "至" + client.getInetAddress().getHostAddress() + ":" + String.valueOf(client.getPort())); out.write(mess);//按字節發送 out.flush(); MyLog.i(TAG1, "發送成功"); Message msg = outHandler.obtainMessage(); msg.obj = mess; msg.what = 1; outHandler.sendMessage(msg);// 結果返回給UI處理 } else { MyLog.i(TAG, "client 不存在"); Message msg = outHandler.obtainMessage(); msg.obj = mess; msg.what = 0; outHandler.sendMessage(msg);// 結果返回給UI處理 MyLog.i(TAG, "連接不存在重新連接"); conn(); } } catch (Exception e) { MyLog.i(TAG1, "send error"); e.printStackTrace(); } finally { MyLog.i(TAG1, "發送完畢"); } } /** * 關閉連接 */ public void close() { try { if (client != null) { MyLog.i(TAG, "close in"); in.close(); MyLog.i(TAG, "close out"); out.close(); MyLog.i(TAG, "close client"); client.close(); } } catch (Exception e) { MyLog.i(TAG, "close err"); e.printStackTrace(); } } }
參考: