views:

111

answers:

1

Hello,

I am currently working on some game made in C# XNA. Since I need to send a huge chunk of data over net (bout 96kb), I am using some string compressor/decompressor code, which I found on the internet. The code looks like this:

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

It works like this: - Server compresses the string using string compressor, where after sending it to the client. - The client receives the compressed string, and decompress it so it is usable.

Now the weird part is, that the code works when I am testing the game alone, which means I run the server and client on the same machine. It also works when I am testing with my friend, where he hosts the server, and I connect. But it ain't working for my friend when I am hosting the server and he connects. When he connects to my server, he receives "Index out of range" at "int msgLength = BitConverter.ToInt32(gzBuffer, 0);". Sometimes he is lucky and gets in, but mostly it fails and returns that error. Can it be that the server ain't getting the whole string sent? I am using Lidgren gen3 for network sending, and the compressed string is sent as netMsg.Write(compressedstring);

Any ideas :) ? Thanks!

+2  A: 

You're making the same incorrect assumption in multiple places: that Stream.Read will return all the data you've asked for in one go. You're ignoring the return value. Don't do that... admittedly it should be okay for MemoryStreams, assuming there's enough dataAdditionally, you may want to use the MemoryStream.ToArray method to convert to a byte array.

Now, you haven't shown how the client is receiving the string - where are you getting it from?

You should log the string that the server sends, and the string that the client receives. That's the absolute first step, so you can see whether the data has actually been preserved.

I suspect that the client is trying to decompress an empty string - i.e. that Convert.FromBase64 is returning an empty byte array - but until you know the string that's being received, it's hard to make any progress.

Jon Skeet
Hi Jon Skeet,I tried your advice logging the string that is sent. Turns out the client did not receive anything, so I guess I need to work with the sending.Thanks for your help :)
Mark