سؤال

في وثائق من الأجهزة التي تتيح لنا السيطرة عليه عبر UDP / IP، لقد وجدت جزء التالية:

<اقتباس فقرة>   

في هذا البروتوكول الاتصالات، DWORD هو البيانات 4 بايت، WORD هو البيانات 2 بايت،   BYTE هو البيانات بايت واحد. تنسيق تخزين غير endian قليلا، وهي يتم تخزين 4 بايت (32bits) البيانات على النحو التالي: D7-D0، D15-D8، D23-D16، D31-D24. بايت مزدوج يتم تخزين (16bits) البيانات على النحو التالي: D7-D0، D15-D8

وأنا أتساءل كيف أن هذا يترجم إلى C #؟ هل يجب علي تحويل الاشياء قبل إرسالها عبر؟ على سبيل المثال، إذا كنت ترغب في إرسال أكثر من عدد صحيح 32 بت أو سلسلة 4 الشخصية؟

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

المحلول

وC # في حد ذاته لا يحدد endianness. كلما قمت بتحويل بايت، ومع ذلك، كنت اتخاذ خيار. و BitConverter الطبقة لها <لأ href = "HTTP: / /msdn.microsoft.com/en-us/library/system.bitconverter.islittleendian.aspx "يختلط =" noreferrer "> المجال IsLittleEndian أن أقول لكم كيف سوف تتصرف، لكنه لا يعطي هذا الاختيار. الشيء نفسه ينطبق على BinaryReader / BinaryWriter.

مكتبة MiscUtil لديه الدرجة EndianBitConverter الذي يسمح لك لتحديد endianness. هناك مكافئات مماثلة لBinaryReader / الكاتب. لا دليل استخدام الانترنت وأخشى، ولكنها تافهة:)

و(وقد EndianBitConverter أيضا قطعة من الوظائف التي ليست موجودة في BitConverter العادي، الذي هو أن تفعل التحويلات في نفس المكان في صفيف بايت).

نصائح أخرى

ويمكنك أيضا استخدام

IPAddress.NetworkToHostOrder(...)

لالقصير، صحيح أو طويل.

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

bool le = BitConverter.IsLittleEndian;

واعتمادا على ما يقول هذا، قد ترغب في عكس أجزاء من المخازن الخاصة بك. بدلا من ذلك، جون السكيت ديه محولات معينة-endian هنا (ابحث عن EndianBitConverter).

ملحوظة أن itaniums (على سبيل المثال) هي كبيرة-endian. معظم إنتل هي Endian طفيف.

ورد على UDP / IP معين ...؟

وتحتاج لمعرفته حول ترتيب البايت الشبكة، فضلا عن وحدة المعالجة المركزية endian نيس.

وعادة لTCP / UDP األوامر، وكنت دائما تحويل البيانات إلى الشبكة ترتيب بايت باستخدام في وظيفة htons (ووntohs، والوظائف المرتبطة بها).

وعادة ترتيب شبكة كبيرة-endian، ولكن في هذه الحالة (لسبب ما!) للتعليق هو endian قليلا، حتى تلك الوظائف ليست مفيدة للغاية. هذا أمر مهم لأن لا يمكنك تحمل األوامر UDP التي نفذت اتباع أي معايير أخرى، كما أنه يجعل الحياة صعبة إذا كان لديك العمارة الكبيرة endian كما كنت فقط لا يمكن التفاف كل شيء مع htons كما يلي: - (

ومع ذلك، إذا كنت قادما من بنية إنتل x86 و ثم كنت بالفعل Endian طفيف، وذلك فقط إرسال البيانات دون تحويل.

إذا كنت تحليل والأداء ليست حرجة، والنظر في هذا رمز بسيط جدا:

private static byte[] NetworkToHostOrder (byte[] array, int offset, int length)
{
    return array.Skip (offset).Take (length).Reverse ().ToArray ();
}

int foo = BitConverter.ToInt64 (NetworkToHostOrder (queue, 14, 8), 0);

وأنا حول اللعب مع البيانات معبأة في UDP المتعدد وأنا في حاجة إلى شيء لإعادة ترتيب الثمانية UInt16 منذ لاحظت خطأ في رأس الحزمة (إيثار ريال)، لذلك جعل هذا:

    private UInt16 swapOctetsUInt16(UInt16 toSwap)
    {
        Int32 tmp = 0;
        tmp = toSwap >> 8;
        tmp = tmp | ((toSwap & 0xff) << 8);
        return (UInt16) tmp;
    }

في حالة UInt32،

    private UInt32 swapOctetsUInt32(UInt32 toSwap)
    {
        UInt32 tmp = 0;
        tmp = toSwap >> 24;
        tmp = tmp | ((toSwap & 0xff0000) >> 8);
        tmp = tmp | ((toSwap & 0xff00) << 8);
        tmp = tmp | ((toSwap & 0xff) << 24);
        return tmp;
    }

وهذا هو فقط للاختبار

    private void testSwap() {
        UInt16 tmp1 = 0x0a0b;
        UInt32 tmp2 = 0x0a0b0c0d;
        SoapHexBinary shb1 = new SoapHexBinary(BitConverter.GetBytes(tmp1));
        SoapHexBinary shb2 = new SoapHexBinary(BitConverter.GetBytes(swapOctetsUInt16(tmp1)));
        Debug.WriteLine("{0}", shb1.ToString());
        Debug.WriteLine("{0}", shb2.ToString());
        SoapHexBinary shb3 = new SoapHexBinary(BitConverter.GetBytes(tmp2));
        SoapHexBinary shb4 = new SoapHexBinary(BitConverter.GetBytes(swapOctetsUInt32(tmp2)));
        Debug.WriteLine("{0}", shb3.ToString());
        Debug.WriteLine("{0}", shb4.ToString());
    }

والذي الانتاج كان هذا:

    0B0A: {0}
    0A0B: {0}
    0D0C0B0A: {0}
    0A0B0C0D: {0}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top