使用固定長度的 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!!");
}
}
===================================
http://www.dotblogs.com.tw/billchung/archive/2012/02/05/67809.aspx
const
Int32 S = 83;
const
Int32 E = 69;
private
void
DoReceive()
{
List<Byte> tempList = new
List<Byte>();
while
(receiving)
{
Int32 receivedValue = comport.ReadByte();
switch
(receivedValue)
{
case
S:
tempList.Clear();
tempList.Add((Byte)receivedValue);
break;
case
E:
tempList.Add((Byte)receivedValue);
parse(tempList);
break;
case
-1:
break;
default:
tempList.Add((Byte)receivedValue);
break;
}
}
}