.NET Heral Port Help مطلوب، في المقام الأول مع البيانات المستلمة في العديد من "الحزم"

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

  •  23-08-2019
  •  | 
  •  

سؤال

أنا جديد جدا لإرسال البيانات عبر منفذ تسلسلي عبر .NET ولقد لاحظت بعد تنفيذ نظير TCP الذي لن أحصل عليه بهذه السهولة باستخدام المسلسل!

لذا البدء في القمة، أنا هناك تقريبا مع تطبيق الاتصالات ثنائي الاتجاه التسلسلي، أنا فقط عالق في بعض الأشياء: -

  1. يتم تقسيم القراءات عبر رسائل متعددة أو استلمت كاستجاب مجزأ عبر منفذ COM ولا أعرف الإعدادات التي قد أحتاج إليها، أو كيف يجب أن أكتب الرمز بشكل مختلف لإصلاح هذا. ماذا يمكن أن يسبب هذا؟ أنا أفقد الرسالة عند نقطة توقف على SerialPort_DataReceived.

أساسا يجب إرسال البيانات على النحو التالي:

01: LS|DA090521|TI111043|q
02: PS|RN102|PTC|TA1040000|P#0|DA090521|TI111429|j

ولكن يتم تقسيمه (في مناصب عشوائية على كل قراءة مطلوبة)

01: LS|DA090521|TI111
02: 043|q
03: PS|RN102|PTC|TA1
04: 0000|P#0|DA090521|TI111429|j

- تم الرد على السؤال 1، شكرا كريس دبليو وغيرها! لدي الآن الرسالة التي أتوقع أن يتم بناؤها من شظايا تدريجية (بحثا عن STX، {MSG Body}، ETX) ثم إجراء يؤدي عند إنشاء رسالة بالكامل، وحصلت على الذهاب مع قائمة انتظار آمنة للخيط، سعيدة للغاية وبعد

. وبعد 2. أنا أتلقى "|" رمز من خلال قرأتي تقريبا كل دورة، هل هذا بسبب أمر قمت بتعيينه بطريقة خاطئة بطريقة أو بأخرى، أو قطعة أثرية من الاتصالات التسلسلية، أو أي شيء يرسله لي الجهاز؟ (لا أعتقد ذلك، حيث أن اتصال HyperTerminal يكشف أن هذه الشخصية لا يتم إرسالها بشكل مستمر.)

وبعد 3. يمكنك تأكيد أنني أقرأ وكتابة البيانات بشكل صحيح في الأساليب المعنية.

شكرا يا شباب للنظر في سؤالين الآخرين أيضا.

رمز ذات صلة على النحو التالي:

...
    //                          COM3,    9600,     None,   8,        One
    SerialPort = new SerialPort(comPort, baudRate, parity, dataBits, stopBits);
    if (SerialPort.IsOpen) SerialPort.Close();
    // SerialPort.RtsEnable = true; // Request-to-send
    // SerialPort.DtrEnable = true; // Data-terminal-ready
    SerialPort.ReadTimeout = 150; // tried this, but didn't help
    SerialPort.WriteTimeout = 150; // tried this, but didn't help
    SerialPort.Open();

    SerialPort.DataReceived += new SerialDataReceivedEventHandler(SerialPort_DataReceived);
}

void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    // Process received data
    SerialPort sp = (SerialPort)sender;
    byte[] buffer = new byte[sp.BytesToRead];
    int bytesRead = sp.Read(buffer, 0, buffer.Length);

    // message has successfully been received
    message = Encoding.ASCII.GetString(buffer, 0, bytesRead);
}

public bool SendMessage(string text)
{
    // Only send message if a client is connected
    if (SerialPort != null && SerialPort.IsOpen)
    {
        byte[] buffer = Encoding.ASCII.GetBytes(text);
        SerialPort.Write(buffer, 0, buffer.Length);
    }
}
هل كانت مفيدة؟

المحلول

يتم تقسيم قراءاتي عبر رسائل متعددة

هذا أمر طبيعي، متوقع، أمر لا مفر منه. يمكن أن يحدث مع بيانات TCP أيضا. إلى الواجهة التسلسلية انها مجرد دفق لا نهاية لها من البايتات. تقع على عاتق طلبك مسؤولية إعادة تعيين تلك البايتات في حزم.

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

أنا أتلقى "|" رمز من خلال قراءتي تقريبا كل دورة

ما هي قيمة HEX هذه الشخصية؟ معرفة ما إذا كان إعداد Handshake الممتلكات إلى XOnXOff أو RequestToSendXOnXOff يحسن الوضع.

نصائح أخرى

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

        p = new SerialPort(PortName, BaudRate, Prty, DataBits, SBits);
        p.NewLine = Terminator;

حيث Terminator هو سلسلة تحتوي على حرف (شخصيات) إنهاء. ثم يمكنك استخدام SerialPort.Readline () (و SerialPort.Writeline () إذا كان ذلك ينطبق). قد يساعد هذا على الأقل في مشكلتك الأولى.

لقد فعلت الكثير من برمجة المنفذ التسلسلي Win32، ولكن قليلا مع .NET، لذلك خذ نصيحتي مع حبة الملح.

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

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

إذا كنت ترغب في الحصول على مزيد من البيانات، يمكنك تجربة ما يلي:

  • ضبط System.int32 استلام الممتلكات
  • باستخدام I / O متزامن وتحديد عدد ثابت من البايتات لقراءة وحدة الاستقبال المستندة إلى الأحداث

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

إذا كنت فضوليا حول ما يجري عبر الخط، تحقق من portmon من sysinternals., ، تطبيق مجاني من شأنه أن يصف منفذ COM الخاص بك أثناء نقل البيانات عبر السطر. يبدو التقنيا، ولكن في الحقيقة عليك أن تنظر إلى أوامر IRP_MJ_WRITE و IRP_MJ_READ، وعلى السطر سترى طول البايت والبيانات المرسلة عبر السلك. مع هذا، يجب أن تكون قادرا على معرفة ما إذا كانت المشكلة هي كائن .NET SerialPort أو إذا كان الجهاز يرسل بالفعل "|" على الخط.

يمكنك تأكيد أنني أقرأ وكتابة البيانات بشكل صحيح في الأساليب المعنية.

يبدو مناسبا لطريقة تلقي البيانات القائمة على الأحداث.

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