Pergunta

Atualmente, estou trabalhando em algum jogo feito em C# XNA. Como preciso enviar uma grande parte dos dados sobre a rede (luta de 96kb), estou usando algum código de compressor/descompressor de string, que encontrei na Internet. O código se parece com o seguinte:

        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);
        }
    }

Funciona assim: - O servidor comprime a string usando o String Compressor, onde depois de enviá -lo para o cliente. - O cliente recebe a sequência compactada e a descompacte para que seja utilizável.

Agora, a parte estranha é que o código funciona quando estou testando o jogo sozinho, o que significa que eu executo o servidor e o cliente na mesma máquina. Também funciona quando estou testando com meu amigo, onde ele hospeda o servidor, e eu conecto. Mas Não está funcionando para meu amigo quando estou hospedando o servidor e ele se conecta. Quando ele se conecta ao meu servidor, ele recebe "índice fora do alcance" em "int msglength = bitconverter.toint32 (gzbuffer, 0);".Às vezes, ele tem sorte e entra, mas principalmente falha e retorna esse erro. Será que o servidor não está enviando a string inteira? Estou usando o Lidgren Gen3 para envio de rede e a sequência compactada é enviada como netmsg.write (comprimedString);

Alguma ideia :) ? Obrigado!

Foi útil?

Solução

Você está fazendo a mesma suposição incorreta em vários lugares: que Stream.Read retornará todos os dados que você pediu de uma só vez. Você está ignorando o valor de retorno. Não faça isso ... é certo que deveria estar bem para MemoryStreams, assumindo que há dados suficientes, você pode querer usar o MemoryStream.ToArray Método para converter em uma matriz de bytes.

Agora, você não mostrou como o cliente está recebendo a string - de onde você está obtendo?

Você deve registrar a string que o servidor envia e a string que o cliente recebe. Esse é o primeiro passo absoluto, para que você possa ver se os dados foram realmente preservados.

Eu suspeito que o cliente esteja tentando descomprimir uma corda vazia - ou seja, isso Convert.FromBase64 está retornando uma matriz de bytes vazia - mas até você conhecer a string que está sendo recebida, é difícil fazer qualquer progresso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top