Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

0xff != "\xff" ??!! 1

Status
Not open for further replies.

AtomicChip

Programmer
May 15, 2001
622
CA
I'm wondering if anybody else has run across this and found out whether or not this is an actual .NET issue, or if it's just another one of those PEBKAC (Problem Exists Between Keyboard And Chair) issues.

I recently created a little class to query Counter Strike (yeah, geeky I know) servers. Each of the server commands are prefixed with 0xff 0xff 0xff 0xff. If I create a byte array like this:

Code:
byte[] b = { 0xff, 0xff, 0xff, 0xff, (Rest of the command here) };

... when this is sent over a socket, there isn't an issue. However, I'm lazy and I don't want to create a byte array like this for each and every command. So, I tried doing this:

Code:
byte[] b = System.Text.ASCIIEncoding.ASCII.GetBytes("\xff\xff\xff\xffCOMMAND\x00");

It seems that when the conversion is done here, the \xff's are actually converted to \x3f's.

I did the exact same thing in Python ("\xff\xff\xff\xffCOMMAND\x00") and it works fine.

.NET issue, or PEBKAC?

Anyone?

-----------------------------------------------
"The night sky over the planet Krikkit is the least interesting sight in the entire universe."
-Hitch Hiker's Guide To The Galaxy
 
I think the issue is that the string constant in your code:
"\xff\xff\xff\xffCOMMAND\x00"
is a Unicode string, and you're using the ASCII getBytes on it. My guess is that it's treating it as a UTF-8 string, which uses the 6 lower bits to store values. This means that your 0xff (11111111 in binary) comes out as 0x3f (00111111 in binary).

I'm not familiar with Counter Strike, but if it has a limited number of commands, defining some static property get's to return them to you?

Chip H.


____________________________________________________________________
If you want to get the best response to a question, please read FAQ222-2244 first
 
Here is how I sent some commands over a socket using string :
string vCmd =".....";
Byte[] b = System.Text.Encoding.ASCII.GetBytes(vCmd.ToCharArray());

-obislavu-
 
Thanks for the reply chip... I'll try that out later (when i get home from work... when i get time... :p), although I'm pretty sure I already tried the Unicode conversion and had the same problem with that.

BTW - Not sure why this would be a unicode string as you stated - there aren't any special characters or anything... it's just straight ASCII (the \x just converts straight to hex, doesn't it? - everything other than the \xff is converting properly)...

Gawd I love socket/hex programming ;) No really... I do :)

Other than that... Just thought I'd mention - Python rocks for prototyping stuff like this... Same functionality, only a third of the code... AWESOME!

-----------------------------------------------
"The night sky over the planet Krikkit is the least interesting sight in the entire universe."
-Hitch Hiker's Guide To The Galaxy
 
BTW - Not sure why this would be a unicode string as you stated - there aren't any special characters or anything... it's just straight ASCII (the \x just converts straight to hex, doesn't it? - everything other than the \xff is converting properly)...

Character strings in .NET are Unicode, not ASCII, nor ANSI. If you want to generate a Unicode character, use \xabcd, where 'abcd' is a 4-digit hex value. MSDN says this about character values:
MSDN said:
The Char value type represents a Unicode character, also called a Unicode code point, and is implemented as a 16-bit number ranging in value from hexadecimal 0x0000 to 0xFFFF.

Once you've created a Unicode character, you can convert it to ASCII (which is probably what Counter Strike is expecting) using the ASCIIEncoding class. Which has this to say:
MSDN said:
The ASCIIEncoding class encodes Unicode characters as single 7-bit ASCII characters. This encoding only supports character values between U+0000 and U+007F.
Chip H.


____________________________________________________________________
If you want to get the best response to a question, please read FAQ222-2244 first
 
Hmm. I think I need to append to my previous answer.

The value you're trying to send is \x00ff, which is outside the range supported by the ASCIIEncoding class (note how it says the max it supports is \x007f).

I ran some tests.

ASCIIEncoding
Code:
public static byte[] CS_Command_1
{
	get 
	{
		const string cmd = "\x00ff\x00ff\x00ff\x00ffCOMMAND\x0000";
		ASCIIEncoding ascii = new ASCIIEncoding();
		return ascii.GetBytes(cmd);
	}
}
Produces:
[3F][3F][3F][3F][43][4F][4D][4D][41][4E][44][0]

UTF8Encoding
Code:
public static byte[] CS_Command_1
{
	get 
	{
		const string cmd = "\x00ff\x00ff\x00ff\x00ffCOMMAND\x0000";
		UTF8Encoding uni = new UTF8Encoding();
		return uni.GetBytes(cmd);
	}
}
Produces:
[C3][BF][C3][BF][C3][BF][C3][BF][43][4F][4D][4D][41][4E][44][0]

UnicodeEncoding
Code:
public static byte[] CS_Command_1
{
	get 
	{
		const string cmd = "\x00ff\x00ff\x00ff\x00ffCOMMAND\x0000";
		UnicodeEncoding uni = new UnicodeEncoding();
		return uni.GetBytes(cmd);
	}
}
Produces:
[FF][0][FF][0][FF][0][FF][0][43][0][4F][0][4D][0][4D][0][41][0][4E][0][44][0][0][0]

So, none of them are exactly what you're looking for so far. But this seems to work:
Code:
public static byte[] CS_Command_1
{
	get 
	{
		Byte[] b = {0xFF, 0xFF, 0xFF, 0xFF, 0x43,
					0x4F, 0x4D, 0x4D, 0x41, 0x4E,
					0x44, 0x0};
		return b;
	}
}
Produces:
[FF][FF][FF][FF][43][4F][4D][4D][41][4E][44][0]

Hope this helps. Not exactly what you were looking for, I know, but by putting it in a static getter property, at least you only have to write it once for each command. By using a method instead of a property, you could pass in values.

Chip H.


____________________________________________________________________
If you want to get the best response to a question, please read FAQ222-2244 first
 
chip,

Yeah, those are pretty much the same results that I got with the tests that I ran when I first ran into this issue. You are correct - the byte array works perfectly when using the 0xff format. I was looking more to make it human-readable.

However, I don't think I've seen this much effort put into a post anywhere else (mind you, I also haven't read all of them ;))...

Star for you, sir.

Thanks for the help :)

BTW - The only workaround that I came up with for this (with using the human-readable format) was to use the ASCIIEncoding.ASCII.GetBytes method with the command string (as in what I was doing before, which didn't work) to create the send buffer, and then just before sending over the socket, copy a byte[] b = { 0x00, 0x00, 0x00, 0x00 }; over the first four elements of the command array. FUGLY!

-----------------------------------------------
"The night sky over the planet Krikkit is the least interesting sight in the entire universe."
-Hitch Hiker's Guide To The Galaxy
 
That's a reasonable solution -- define a property for a "command prefix" which has the ugly "0xFF" byte array values in it, and use it to concatenate up the real command.

Chip H.


____________________________________________________________________
If you want to get the best response to a question, please read FAQ222-2244 first
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top