2014-03-17 4 views
2

Я работаю над этим около часа, и я не могу получить uint16, упакованный в правильном формате на C#.Преобразование PHP в C#

РНР:

$data = "\x00"; //packet id 
$data .= "\x04"; //protocol version 
$data .= pack('c', strlen($server_address)) . $server_address; //server address 
$data .= pack('n', $server_port); //server port 
$data .= "\x01"; //next state 

$data = pack('c', strlen($data)) . $data; 

return $data; 

C#

string packet_id = "\x00"; 
string protocol_version = "\x04"; 
string server_address = new string(new char[] { Convert.ToChar(this.server_address.Length) }) + this.server_address; 
//byte[] port_array = BitConverter.GetBytes((ushort)this.server_port); 
//Array.Reverse(port_array); 
string server_port = Convert.ToString((ushort)this.server_port); 
string next_state = "\x01"; 

string final = packet_id + protocol_version + server_address + server_port + next_state; 
final = new string(new char[] { Convert.ToChar(final.Length) }) + final; 

Результаты в гекс заключаются в следующем: РНР:

12 00 04 0C 31 39 38 2E 32 37 2E 38 33 2E 33 35 63 DE 01 

C#

15 00 04 0C 31 39 38 2E 32 37 2E 38 33 2E 33 35 32 35 35 36 36 01 

Как вы видите, порт сервера (25566) - это 63 DE на PHP, но 32 35 35 36 36 в C#.

+0

Не означает «\ x01» значение x? Не должно быть @ "\ x01"? (то же самое с остальными строками, которые имеют x) –

+0

C# пишет порт сервера как строку, он должен записывать его как число –

+0

Это строка, которую я собираюсь отправить в сокет, сервер очень придирчив к форматирование, поэтому оно должно быть точным, и я не могу эмулировать пакет php («n», «..»); работает должным образом. –

ответ

1

Самый простой способ сделать это с байтовый массив и побитовые операции:

byte[] data = new byte[] { 
    (byte) (((ushort) this.server_port) >> 8), 
    (byte) ((ushort) this.server_port) 
}; 
string server_port = (string) data; 

Стоит также отметить, что ваш вывод PHP на самом деле изображает 25565, не25566. Как вы можете видеть here, 25566 на самом деле 63DE в гексагоне.

+0

Я не думаю, что вы можете придать байтовый массив как строку. –

+0

Так что технически я подражаю php's pack («n», ..) с C#, что означает uint16 в формате большого эндиана. –

0

Я предлагаю вам использовать этот код для преобразования порта:

this.server_port.ToString("X") 

Он преобразует число, которое вы дали шестнадцатеричное представление в строке

+0

Это будет делать правильный вывод, но это сделает его 63DE как текст, а не шестнадцатеричным. –

0

Вы пытаетесь пинговать сервер? Я предлагаю использовать Craft.Net, вместо того, чтобы пытаться катиться самостоятельно.

+0

Это не помогает мне узнать сокеты в малейшей степени, спасибо за предложение. –

+0

Вы никогда не говорили, что пытаетесь узнать сокеты. Этот ответ решает вашу проблему. –

Смежные вопросы