Jump to content
  • Advertisement
Sign in to follow this  
Kryptus

Ignoring the null termination...

This topic is 4832 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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...

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!