使用固定長度的 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!!");
}
}