Using blocking sockets in c#, I have a timer on 10ms delay that checks for new data like so:
static void timerTick()
{
if (stmBnet.DataAvailable)
{
int i = stmBnet.Read(RecvData, 0, size);
if (i > 0)
{
//data exists, separate it up and remove the null bytes
SplitPacket(RecvData);
if (DataQ.Count > 0)
{
//parse the separated packets
ParsePackets();
}
RecvData = new byte[size]; //reset the buffer
}
}
}
I receive the data fine but the issue is that sometimes it clumps together and adds a plethora of trailing 0x00 (null) bytes. Therefore I wrote the packet splitting function, which splits up thepackets and places the data into a queue (DataQ):
static void SplitPacket(byte[] bData)
{
for (int i = 0; i < bData.Length; i++)
{
if (bData[i] == (byte)0xff)
{
//found 0xFF, check if it's a header
if (bData.Length >= i + 2) //check that we can move up 2 more bytes to check for packet size
{
//i is still the location of 0xFF
byte packetid = bData[i + 1];
int packetsize = BitConverter.ToInt16(bData, i + 2);
if (bData.Length >= i + (packetsize - 1) && packetsize > 3 && packetsize < 512)
{
Console.WriteLine("Packet ID: 0x{0} :: Size: {1}", packetid.ToString("x2"), packetsize);
string splitPacket = Encoding.Unicode.GetString(bData, i, packetsize);
DataFormatter.WriteToConsole(Encoding.Unicode.GetBytes(splitPacket));
DataQ.Add(splitPacket);
}
}
}
}
}
I then go about parsing the items in the queue. However, for some reason, it will randomly occur that the end of my parsed packets have the bytes: 0xFD and 0xFF, and are 1 beyond the split size.. for example, if the real packet data is
FF 30 09 00 01 00 00 00 00
, the packet splitter function will somehow end up with
FF 30 09 00 01 00 00 00 FD FF
instead.
I think it has something to do with the data being extracted as a string:
string splitPacket = Encoding.Unicode.GetString(bData, i, packetsize);
But I'm not sure how to extract in the middle of a byte array (the equivalent of .substring for byte[]). I think the null terminator on the end of packets is getting lost when it's extracted.
I'm basically looking for the C# equivalent of the java method extractBytes.
Nevermind, ended up using Array.copy. Revised funct:
static void SplitPacket(byte[] bData)
{
for (int i = 0; i < bData.Length; i++)
{
if (bData[i] == (byte)0xff)
{
//found FF, check if it's a header
if (bData.Length >= i + 2) //check that we can move up 2 more bytes to check for packet size
{
byte packetid = bData[i + 1];
int packetsize = BitConverter.ToInt16(bData, i + 2);
if (bData.Length >= i + (packetsize - 1) && packetsize > 3 && packetsize < 512)
{
//we have enough room to separate the packet, it is a valid BNCS packet\
Console.WriteLine("Packet ID: 0x{0} :: Size: {1}", packetid.ToString("x2"), packetsize);
byte[] tempData = new byte[packetsize];
Array.Copy(bData, i, tempData, 0, packetsize);
DataFormatter.WriteToConsole(tempData);
DataQ.Add(tempData);
}
}
}
}
}
I'll leave the thread here on the off chance that someone else has a similar issue.