سؤال

أنا أعمل حاليًا على بعض الألعاب التي صنعت في C# XNA. نظرًا لأنني بحاجة إلى إرسال جزء كبير من البيانات عبر Net (Bout 96 كيلو بايت) ، فأنا أستخدم بعض كود ضاغط/إلغاء ضغط السلسلة ، الذي وجدته على الإنترنت. الرمز يشبه هذا:

        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 ، على افتراض أن هناك ما يكفي من البيانات ، قد ترغب في استخدام MemoryStream.ToArray طريقة للتحويل إلى صفيف بايت.

الآن ، لم تظهر كيف يتلقى العميل السلسلة - من أين تحصل عليها؟

يجب عليك تسجيل السلسلة التي يرسلها الخادم ، والسلسلة التي يتلقاها العميل. هذه هي الخطوة الأولى المطلقة ، حتى تتمكن من معرفة ما إذا كانت البيانات قد تم الحفاظ عليها بالفعل.

أظن أن العميل يحاول إلغاء ضغط سلسلة فارغة - أي ذلك Convert.FromBase64 يعيد صفيف بايت فارغ - ولكن حتى تعرف السلسلة التي يتم استلامها ، من الصعب إحراز أي تقدم.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top