Проблема с кодом, преобразованным из C ++ в C # - PullRequest
1 голос
/ 12 марта 2011

Я преобразовал некоторый код из приложения C ++, которое я написал давным-давно, в C #. В C ++ у меня была библиотека, которая использовала битовый буфер, но отсутствие знаний C # несколько усложнило преобразование.

Когда я запрашиваю свое приложение, и я просто использую ByteWriter без правильного приведения каких-либо значений (как bf.Write (-1) и bf.Write ("stringhere"), программы запроса по крайней мере запрашивают его, просто ошибаются) информация. Когда я правильно приводил значения (к длинному, байтовому, короткому и т. д.), он полностью разрывается, и приложение-запрос его даже не видит.

Фрагмент кода C ++

void PlayerManager::BuildReplyInfo()
{   
    // Delete the old packet
    g_ReplyInfo.Reset();

    g_ReplyInfo.WriteLong(-1);
    g_ReplyInfo.WriteByte(73);
    g_ReplyInfo.WriteByte(g_ProtocolVersion.GetInt());
    g_ReplyInfo.WriteString(iserver->GetName());    
    g_ReplyInfo.WriteString(iserver->GetMapName()); 
    g_ReplyInfo.WriteString(gGameType);
}

C # код

public static byte[] ConvertStringToByteArray(string str)
{
    System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
    return encoding.GetBytes(str);
}

// -----------------------------------

    while (true)
    {
        data = new byte[1024];
        recv = socket.ReceiveFrom(data, ref Remote);

        Console.WriteLine("Message length is " + recv);

        // If the length is 25 and the 5th byte is 'T' it is a A2S_INFO QUERY
        if (recv == 25 && data[4] == 84)
        {
            Console.WriteLine("Source Engine Query!");

            data = BuildReplyInformation();
            socket.SendTo(data, 0, data.Length, SocketFlags.None, Remote);
        }
    }
}

public static byte[] BuildReplyInformation()
{
    MemoryStream stream = new MemoryStream();
    BinaryWriter writer = new BinaryWriter(stream);

    writer.Write((long)(-1));
    writer.Write((byte)(73)); // Steam Version
    writer.Write((byte)(15)); // Protocol
    writer.Write(ConvertStringToByteArray("Minecraft Server\0")); // Hostname
    writer.Write(ConvertStringToByteArray("Map Name\0")); // Map Name
    writer.Write(ConvertStringToByteArray("tf\0")); // Game Directory
    writer.Write(ConvertStringToByteArray("Minecraft Server\0")); // Game Description
    writer.Write((short)(440));
    writer.Write((byte)(15)); // Players
    writer.Write((byte)(32)); // Max Players
    writer.Write((byte)(0)); // Bots
    writer.Write((byte)(100));
    writer.Write((byte)(119)); // 108 Linux, 119 Windows
    writer.Write((byte)(0)); // Password Boolean
    writer.Write((byte)(01)); // Vac Secured
    writer.Write(ConvertStringToByteArray("1.1.3.7\0"));

    return stream.ToArray();
}

Ответы [ 3 ]

0 голосов
/ 12 марта 2011

Только несколько вещей, которые нужно иметь в виду:

  1. Строки UTF-8 иногда начинаются с спецификации (метки порядка байтов), иногда нет.
  2. Строки иногда имеют префикс сериализованной длины, иногда заканчиваются нулем.

Мое предложение состоит в том, чтобы дважды проверить оригинальный метод C ++ WriteString (...), чтобы выяснить, как он ведет себя по отношению к # 1 и # 2, а затем дважды проверить метод C # GetBytes (...) для того же. Насколько я помню, двоичный сериализатор .NET записывает строки с префиксом длины для каждой записанной строки, а кодировщик UTF8 - нет (и также не выводит нулевой символ). Кодер UTF8 также может (в зависимости от того, как вы его используете?) Выводить спецификацию.

Также я подозреваю, что \ 0 может быть записано при прохождении через кодировщик UTF8. Вы можете (для ударов) попытаться вывести нулевой маркер отдельно от содержимого строки, как просто байт со значением 0.

0 голосов
/ 12 марта 2011

Длинный размер в C # отличался от C ++, решил проблему.

0 голосов
/ 12 марта 2011

Несколько идей, которые могли бы помочь вам:

  1. Вы уверены, что вам нужно UTF8 в качестве строкового кодирования?
  2. Когда вы смотрите на массив и сравниваете его с предполагаемой структурой, можете ли вы выяснить, в какой момент массив не соответствует стандарту?
...