使用固定長度的 byte 陣列去收 socket 資料時, 若收到的資料長度不為 byte 的長度, 那麼後面的資料就會不完整, 必須與後面的資料合併才會得到完整的資料!!
若沒有注意到這一點, 一收到資料後就立刻轉為字串去進行處理, 就會看到字串的資料後面會都是  \0 .

以下的 SckSReceiveProc() 為接收 Socket 資料的 void ,  紅色字體為處理字串不完整的問題所增加的code.

 

        private void SckSReceiveProc()
        {

            int DataLen = 420, IntAcceptData;  // DataLen 為資料的固定長度, IntAcceptData 則是用來接收有資料的真實長度

            string S;

            byte[] bteAcceptData = new byte[DataLen];               // bteAcceptData 為用來接收固定資料長度的 byte 陣列

            try
            {

                while (true)
                {

                    IntAcceptData = RSck.Receive(bteAcceptData);   // RSck 為 Socket , 正常情況下, IntAcceptData 會等於 DataLen, 若 IntAcceptData 不等於 DataLen 表示這次 Receive 進來的資料不完整

                    // 處理 Receive Data 長度不完整的問題!!
                    // ==============================================
                    if (IntAcceptData != DataLen)
                    {

                              int tmpDataLen = DataLen;                        // tmpDataLen 用來判斷還剩多少資料要收進來!!
                              int StartIndex = 0;                                      // StartIndex 是用來記錄收進來的資料要從第幾個位元開始合併,

                              while (IntAcceptData != tmpDataLen)   // 如果接收的資料長度不等於指定接收的 byte 長度, 表示資料尚不完整要繼續與之後的資料合併
                              {
                                  StartIndex += IntAcceptData;            
                                  tmpDataLen -= IntAcceptData;         

                                  byte[] tmpAcceptData = new byte[tmpDataLen];
                                  IntAcceptData = RSck.Receive(tmpAcceptData);

                                  Array.ConstrainedCopy(tmpAcceptData, 0, bteAcceptData, StartIndex, IntAcceptData);
                              }

                    }

                    // ==============================================

                   
                    S = Encoding.Default.GetString(bteAcceptData);

                    Array.Clear(bteAcceptData, 0, bteAcceptData.Length);
                }
            }
            catch
            {
                Console.WriteLine("Error!!");
            }
        }

arrow
arrow
    全站熱搜

    Keep Practicing 發表在 痞客邦 留言(0) 人氣()