Socket丟包解決對策

socket使用過程中遇到個問題:因爲數據量太大,大約有2w個字節的響應數據報,之前同事代碼實現的時候沒有做完整的接收處理。僅使用InputStream.available()做了一次讀取,然後就遇到問題了!

會發現,每次讀取的時候獲得的長度值不固定,且均無法獲得完整長度。另一方面,響應的數據報並不會告知發送的長度是多少,但是有結束標誌:byte類型 03是結束標誌。

所以做了重新實現:

byte[] buffer = null;
        byte[] tempBuffer = new byte[0];//
        try {
            int count = 0;
            while (true) {
                count = is.available() ;// 返回03 退出
                Logger.debug("count======" + count);
                if (count != 0) {
                    buffer = new byte[count]; // 緩衝區
                    is.read(buffer);
                    tempBuffer = ByteUtils.byteMerger(tempBuffer, buffer);//拼接接收報文
                    LogUtils.d(TAG, "end>>byte>>" + buffer[count -1]);
                    if (buffer[count - 1] == 03) {//03 結束
                        LogUtils.d(TAG, "end while>>count>>" + count);
                        buffer = tempBuffer;
                        break;
                    } else {
                        Thread.sleep(500);
                    }
                } else {
                    Thread.sleep(500);
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
            Logger.debug("Recive:讀取流數據超時異常 =" + e.toString());
            close();
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            close();
            return null;
        }

因爲是多次接收,且次數不固定,所以需要while循環接收,同時寫了工具類進行byte數據的拼接:

public class ByteUtils {

    private static final String TAG = "ByteUtils";

    /**
     * 組合兩個byte數組
     * @param first
     * @param second
     * @return
     */
    public static byte[] byteMerger(byte[] first, byte[] second){
        LogUtils.d(TAG, "byteMarger");
        byte[] temp = new byte[first.length + second.length];
        int i = 0;
        for (byte b : first){
            temp[i] = b;
            i ++;
        }

        for (byte b : second){
            temp[i] = b;
            i ++;
        }
        return temp;

    }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章