I hate making an entire post about it but I'd like some advice on code style. I'm trying to make certain that recv is always getting at least enough information to continue parsing the packet.
total = RecvMsg(buf, client, sizeof(buf));
while (true)//loop until we recieve all of the bytes.
{
if (total >= 3) //header + string size
{
username_size = (buf[0]<<8|buf[1]);
username = newchar[username_size]; //Allocate just enough to hold the playername
break;
}
total += RecvMsg(buf, client, sizeof(buf));
}
while (true)
{
if (total >= (3 + username_size))
{
strncpy(username, buf + 2, username_size);
//TODO: Store in client class
break;
}
total += RecvMsg(buf, client, sizeof(buf));
}
The protocol doesn't give packet size. So, to handle dynamic strings, he places a short before every string that defines how large that string is. This makes this a punk to do nicely it seems. So, I was wondering if there was a more standard way to do this?
Better explanation of code:
The code here tries to recv a message. Then it tests to see if there is enough bytes in the buffer to read the next piece of data we need. If not, it tries to recv more bytes to fulfill the task until it is done.
The protocol doesn't give packet size. So, to handle dynamic strings, he places a short before every string that defines how large that string is. This makes this a punk to do nicely it seems. So, I was wondering if there was a more standard way to do this?
It is perfectly normal. When we design protocol, we either have fixed packet size (easy to debug and develop) or we have variable aka dynamic packet size. So for dynamic, there are a few strategies. The one you mention is simple and effective.
Pattern 1
<packet size len><packet data>
Pattern 2
<packet start byte><packet data><packet end byte> //assume <packet data> cannot have bytes that are from <packet start byte> or <packet end byte>
Actually the time I have to deal with such issues is to do hardware level interfacing program. Imagine a compass and a GPS are mounted on top of a vehicle, they are connected by wires to COMM aka serial (ya I am that old already :) ports.
Then you need to write program to read from COMM port and decipher those bytes to understand the compass and GPS is sending what kind of messages based on the specifications given when you purchase the compass and GPS hardware. Those bytes come in at a furious rate so your program must process them fast enough.
The compass I have used the <packet start byte><packet data><packet end byte> pattern whereas the GPS uses <packet size len><packet data> pattern. As all of them contain their data "meaning" within a single byte, I no need to worry about endian-ness *phew*
But they take it to the extreme, their specifications for e.g read the first byte contain 8 bits and you can have 0x00 to 0xFF all mean different things!!!
This is a classic case when I feel C/C++ shines instead of Java. Once again C/C++ make the mark again!!!! :P