فقدان البايت العشوائي عند دفق البيانات عبر الشبكة

StackOverflow https://stackoverflow.com//questions/20011324

سؤال

مشكلتي هي أنه عندما أقوم ببث دفق مستمر من البيانات عبر شبكة محلية محلية ، تضيع أحيانا وحدات بايت عشوائية في هذه العملية.

كما هو الحال الآن يتم إعداد التعليمات البرمجية لتيار حوالي 1027 بايت أو نحو ذلك ~40 مرة في الثانية على الشبكة المحلية وأحيانا (نادرة جدا) يتم فقدان واحد أو أكثر من وحدات البايت.

الشيء الذي يحير لي هو أن البايت الفعلي ليس "فقدت" يتم تعيين فقط إلى 0 بغض النظر عن البيانات الأصلية.(أنا باستخدام تكب بالمناسبة)

إليك رمز الإرسال:

    public void Send(byte[] data)
    {
        if (!server)
        {
            if (CheckConnection(serv))
            {
                serv.Send(BitConverter.GetBytes(data.Length));
                serv.Receive(new byte[1]);
                serv.Send(data);
                serv.Receive(new byte[1]);
            }
        }
    }

ورمز الاستلام:

    public byte[] Receive()
    {
        if (!server)
        {
            if (CheckConnection(serv))
            {
                byte[] TMP = new byte[4];
                serv.Receive(TMP);
                TMP = new byte[BitConverter.ToInt32(TMP, 0)];
                serv.Send(new byte[1]);
                serv.Receive(TMP);
                serv.Send(new byte[1]);
                return TMP;
            }
            else return null;
        }
        else return null;
    }

إرسال واستقبال وحدات البايت الفارغة هي فقط للحفاظ على النظام في المزامنة شيء على.شخصيا أعتقد أن المشكلة تكمن في الجانب المتلقي للنظام.لم تكن قادرة على إثبات أن طائرة رغم ذلك.

هل كانت مفيدة؟

المحلول

فقط لأنك تعطي Receive(TMP) لا يعني صفيف 4 بايت أنه سيملأ هذا الصفيف بـ 4 بايت.يسمح للمكالمة تلقي لوضع في أي مكان بين 1 و TMP.Length بايت في المصفوفة.يجب عليك التحقق من عاد int لمعرفة عدد بايت من مجموعة حيث شغلها.

اتصالات الشبكة تعتمد على الدفق وليس على الرسائل.أي بايت كنت وضعت على السلك مجرد الحصول على متسلسلة في طابور كبير والحصول على قراءة في على الجانب الآخر عندما تصبح متاحة.لذلك إذا أرسلت المصفوفين 1,1,1,1 و 2,2,2,2 من الممكن تماما أن تتصل على الجانب المتلقي Receive ثلاث مرات مع مجموعة 4 بايت والحصول على

  • 1,1,0,0 (استلام عاد 2)
  • 1,1,2,2 (استلام عاد 4)
  • 2,2,0,0 (استلام عاد 2)

لذا ما عليك القيام به هو إلقاء نظرة على القيم التي عدت منها Receive والحفاظ على حلقات حتى مجموعة بايت الخاص بك هو الكامل.

byte[] TMP = new byte[4];

//loop till all 4 bytes are read
int offset = 0;
while(offset < TMP.Length)
{
    offset += serv.Receive(TMP, offset, TMP.Length - offset, SocketFlags.None);
}
TMP = new byte[BitConverter.ToInt32(TMP, 0)];

//I don't understand why you are doing this, it is not necessary.
serv.Send(new byte[1]); 

//Reset the offset then loop till TMP.Length bytes are read.
offset = 0;
while(offset < TMP.Length)
{
    offset += serv.Receive(TMP, offset, TMP.Length - offset, SocketFlags.None);
}

//I don't understand why you are doing this, it is not necessary.
serv.Send(new byte[1]);

return TMP;

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

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