فقدان البايت العشوائي عند دفق البيانات عبر الشبكة
-
20-12-2019 - |
سؤال
مشكلتي هي أنه عندما أقوم ببث دفق مستمر من البيانات عبر شبكة محلية محلية ، تضيع أحيانا وحدات بايت عشوائية في هذه العملية.
كما هو الحال الآن يتم إعداد التعليمات البرمجية لتيار حوالي 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 من شأنها التعامل معها بالنسبة لك داخل المكتبة.