1. 程式人生 > >Unity3D筆記——Socket粘包分包的理解和最簡單的處理方式

Unity3D筆記——Socket粘包分包的理解和最簡單的處理方式

前言:Unity3D筆記是我平時做一些好玩的測試和研究,記錄的筆記。會比較詳細也可能隨口一提就過了。 所以大家見諒了,內容一般都會是原創的(非原創我會註明轉載)。由於很多內容其他的朋友也肯定研究發表過,大家請指出錯誤。

之前做的答題遊戲,在向伺服器申請題目列表時遇到點問題:由於題目過長,所有傳過來的json格式的資料自動分包了;需要自己處理下;

我列印了下收到資料: 這邊可以明顯看到:本來時一條的資料這裡被分成兩次收到了;於是呢,就沒有辦法直接解析資料了; 一.粘包和分包現象 該現象主要發生在TCP協議中:由於TCP本身的機制,客戶端和伺服器會維持一個連線傳送資料。如果傳送的資料很小,那麼會自動把一些小的資料合併在一起傳送出去;但是接收端就沒辦法自己分開了。這就是粘包現象;而當一次傳送的資料又過長的時候,TCP就會把該資料分成幾部分發送出去,每次接收方就只會接受部分的資料;這就是分包現象; 粘包現象: 客戶端傳送:hello; 客戶端傳送:aaaaa; 伺服器收到:helloaaaaa;
分包現象: 客戶端傳送:helloxiaoming; 伺服器收到:hell 伺服器收到:oxiaoming 就像我遇到的問題一樣:伺服器傳送過來的資料太長了:導致本地的而客戶端分兩次收到了資訊; 二.最簡單的處理方式 最簡單的方式就是在每次傳送資料的時候,在資料的末尾加一個識別符號:該識別符號不能是資料中出現的符號,不能是常用的符號;我用的是(\n) 直接上程式碼: 傳送的處理:
 void loadQuestionAndSend()
    {
        List<Question> questionList = QuestionLoader.Instance.GetListQuestion();

        string questionJson = JsonAndIOHelper.SerializeObject(questionList);

        GameData gameData = new GameData(JsonDataType.questionRoom, questionJson);

        string gameDataJson = JsonAndIOHelper.SerializeObject(gameData);

        SendDataToPlayer(gameDataJson + "\n");
    }
前面是序列化的一些步驟,然後在最後添加了“\n”換行符; 接受端: 先定義個快取的空間:
  //用於存放分包遺留的資料
    private string buffStr="";
收到資料後處理:
//處理收到的資料
            string str = System.Text.Encoding.UTF8.GetString(readBuff,0,count);

            Debug.Log(str);

            //把上次剩下的資料放入
            str = buffStr + str;

            //更具換行符,解析
            string[] line = str.Split('\n');

            for (int i = 0; i < line.Length; i++)
            {
                //最後一個放入新的快取
                if (i == line.Length - 1)
                {
                    buffStr = line[i];
                }
                else
                {
                    Debug.Log(line[i]);

                    NetworkDataHandler.Instance.NetworkDataUpdate(line[i]);
                }


說明: 這邊呢做的事這麼幾部:1.每次收到資料後,把前一次遺留的快取資料加上去;2.根據換行符,隔斷資料,得到資料的陣列;3.前幾個資料都是完整的,最後一個放入緩衝中; 嗯,基本就是這些了; 最後列印下,處理後的資料:可以看到這是完整的json資料了;