Вопрос

В настоящее время я работаю над какой-то игрой, сделанной в C # XNA. Поскольку мне нужно отправить огромную кусок данных по сети (BOT 96KB), я использую несколько строковых компрессоров / декомпрессорного кода, который я нашел в Интернете. Код выглядит так:

        public static string Compress(string text)
    {
        byte[] buffer = Encoding.UTF8.GetBytes(text);
        MemoryStream ms = new MemoryStream();
        using (GZipStream zip = new GZipStream(ms, CompressionMode.Compress, true))
        {
            zip.Write(buffer, 0, buffer.Length);
        }

        ms.Position = 0;
        MemoryStream outStream = new MemoryStream();

        byte[] compressed = new byte[ms.Length];
        ms.Read(compressed, 0, compressed.Length);

        byte[] gzBuffer = new byte[compressed.Length + 4];
        System.Buffer.BlockCopy(compressed, 0, gzBuffer, 4, compressed.Length);
        System.Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gzBuffer, 0, 4);

        return Convert.ToBase64String(gzBuffer);
    }

    public static string Decompress(string compressedText)
    {
        byte[] gzBuffer = Convert.FromBase64String(compressedText);
        using (MemoryStream ms = new MemoryStream())
        {
            int msgLength = BitConverter.ToInt32(gzBuffer, 0);
            ms.Write(gzBuffer, 4, gzBuffer.Length - 4);

            byte[] buffer = new byte[msgLength];

            ms.Position = 0;
            using (GZipStream zip = new GZipStream(ms, CompressionMode.Decompress))
            {
                zip.Read(buffer, 0, buffer.Length);
            }

            return Encoding.UTF8.GetString(buffer);
        }
    }

Это работает так: - Сервер сжимает строку с помощью строкового компрессора, где после отправки его клиенту. - Клиент получает сжатую строку и декомпрессирует ее, так что это полезно.

Теперь странная часть - это, что код работает, когда я проверяю игру в одиночку, что означает, что я запускаю сервер и клиент на одной машине. Он также работает, когда я проверяю с моим другом, где он проводит сервер, и я подключаюсь. Но Это не работает для моего друга, когда я принимаю сервер, и он подключается. Когда он подключается к моему серверу, он получает «индекс из диапазона» на «int Msglength = bitconverter.toint32 (gzbuffer, 0);".Иногда ему повезло и входит, но в основном это не удается и возвращает эту ошибку. Может ли это, что сервер не получает отправленную целую строку? Я использую Lidgren Gen3 для отправки сети, а сжатая строка отправляется в виде NetMSG.WRITE (CompressedString);

Любые идеи :) ? Спасибо!

Это было полезно?

Решение

Вы делаете то же самое неверное предположение в нескольких местах: что Stream.Read вернет все данные, которые вы попросили за один. Вы игнорируете возвращаемое значение. Не делай этого ... по общему признанию, это должно быть в порядке для MemoryStreams, предполагая, что достаточно DAABADDITYALL, вы можете использовать MemoryStream.ToArray Способ преобразования в байтовый массив.

Теперь вы не показали, как клиент получает строку - откуда вы получаете?

Вы должны регистрировать строку, которую сервер отправляет, и строка, которую получает клиент. Это абсолютный первый шаг, так что вы можете увидеть, были ли данные на самом деле сохранены.

Я подозреваю, что клиент пытается распаковать пустую строку - то есть это Convert.FromBase64 Возвращает пустую байтовую массив - но пока вы не знаете строку, которая принимается, трудно добиться прогресса.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top