Ignoring the null termination...

Started by
4 comments, last by gosper 18 years, 9 months ago
G'day, I have written a small program that pings a Counter-Strike Source server and if it exists my program sends a server query packet. The server then returns information like the name, what map, how many players, etc. The thing is that the name and map are null terminated strings and once my program has only received the name it stops because it sees the null termination. Because of this I can't get the map or other string objects. I'm guessing this is my problem. How do I stop this? I'm using C# 2005 but I'm sure the concept will apply to any language. Thanks.
Advertisement
Normally the binary 0 represents the end of a string. So why not just when read a new string again? This should be an easy task of course...
Gaudeamus igitur, iuvenes dum sumus!
It's more or less a thing of "how"

I have the following way I receiving my data,

ServerSocket.BeginReceive(ClientData, 0, ClientData.Length, SocketFlags.None, new AsyncCallback(DoReceive), null);

Let's say for example that the ClientData has a size of 50 characters and the first string ends at character 24, so ClientData[24] = 0x00. The thing is it stops receiving data at that point and doesn't receive the characters 25 through 50.
If you know the length of the total string, which you probably should, then you can chop it up into smaller strings without segfaulting. For instance:
char * input_buffer;int    buff_size;char * name;char * map;char * players;int    x, y;/* query_server( &input_buffer, &buff_size ); */name = input_buffer;y = 0;for (x=0; x<buff_size; x++){  if (input_buffer[x] == 0)  {    switch(y)    {      case 0: map = input_buffer+x+1; break;      case 1: players = input_buffer+x+1; break;      default: break;    }    y+=1;  }}

You use the null terminators to your advantage.

Of course, it'd probably be a lot simpler to change the nulls into linebreaks, but thats up to you.
william bubel
First of all, what makes you think it stops actually receiving data after the null? I see no reason why it should. Winsock does not care about nulls, it will receive until there's no more data coming. I'd say the fault is in your string construction code.

Here's how I'd do it:

private byte[] _LeftoverData = new byte[0];public string GetOneString(byte[] pNewData){// pNewData is any newly received data.// If it's null, process from already received data.if (pNewData == null)    pNewData = new byte[0];// So first, append any new data to previous data.byte[] buffer = new byte[_LeftoverData.Length + pNewData.Length];// Now find whether there is one whole string in there.int null_pos = -1;for (int i = 0; i < buffer.Length; i++){    if (buffer == 0)    {        null_pos = i;        break;    }}if (null_pos == -1)    return null; // No whole string found.// Process all characters up to the null.string result = System.Text.Encoding.ASCII.GetString(buffer, 0, null_pos);// And store leftovers._LeftoverData = new byte[buffer.Length - null_pos - 1];Buffer.BlockCopy(buffer, null_pos + 1, _LeftoverData, 0, _LeftoverData.Length);return result;}


Now just call the function until you get a null to process all already-received strings.
Are you using a non blocking select call? This should solve the problem.

This topic is closed to new replies.

Advertisement