C# 索引超出范围,位于;int-msgLength=BitConverter.ToInt32(gzBuffer,0)&引用;

C# 索引超出范围,位于;int-msgLength=BitConverter.ToInt32(gzBuffer,0)&引用;,c#,networking,xna,bitconverter,outofrangeexception,C#,Networking,Xna,Bitconverter,Outofrangeexception,我目前正在制作一些用C#XNA制作的游戏。 因为我需要通过网络发送大量数据(大约96kb),所以我使用了一些字符串压缩程序/解压缩程序代码,这是我在互联网上找到的。 代码如下所示: public static string Compress(string text) { byte[] buffer = Encoding.UTF8.GetBytes(text); MemoryStream ms = new MemoryStream();

我目前正在制作一些用C#XNA制作的游戏。 因为我需要通过网络发送大量数据(大约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
将一次性返回您要求的所有数据。您忽略了返回值。不要那样做。。。诚然,
MemoryStream
s应该没问题,假设有足够的数据。此外,您可能希望使用
MemoryStream.ToArray
方法将其转换为字节数组

现在,您还没有显示客户机是如何接收字符串的-您从哪里获得它

您应该记录服务器发送的字符串和客户端接收的字符串。这是绝对的第一步,因此您可以查看数据是否已实际保留


我怀疑客户端正在尝试解压缩一个空字符串,也就是说,
Convert.FromBase64
返回一个空字节数组,但是在您知道接收到的字符串之前,很难取得任何进展。

坚持Debug.Assert(gzBuffer.Length>=4);在调用BitConverter.ToInt32()之前,您将看到问题所在。gzBuffer甚至不包含读取Int32的4个字节。嗨,Jon Skeet,我尝试了你的建议,记录发送的字符串。原来客户机没有收到任何东西,所以我想我需要处理发送。谢谢你的帮助:)