C C# - Daten auf dem PC empfangen

Dieses Thema im Forum "Software" wurde erstellt von Janiiix3, 19. November 2018.

  1. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.282
    Zustimmungen:
    8
    Punkte für Erfolge:
    38
    Sprachen:
    C, C#
    Guten Nabend,

    ist villeicht nicht ganz so richtig platziert hier..
    Aber eventuell kann mir ja doch jemand helfen oder hatte sogar schon mal nen ähnliches Problem.

    Mein Problem:
    Bin gerade dabei mir ein kleines PC Tool zu schreiben welches Daten einsammelt und auswertet.
    Da ist auch schon das eigentliche Problem. Das einsammeln klappt bei höheren Baudraten deutlich besser als bei kleineren (<= 9600).

    Ich habe ehrlich gesagt keine Ahnung mehr was ich noch anstellen kann damit es sauber ohne ein "Delay" funktioniert..

    Achja.. Wenn ich ein "Delay" in das Event mit einbaue, sieht es bis jetzt so aus das alles so ankommt und ausgewertet wird wie es eigentlich soll.

    Hier mal der Kode ( ist für den PC )


    CodeBox C und C++
            public void Client_DataReceived(object sender, SerialDataReceivedEventArgs e)
            {
                /* Protokoll
                 *
                 *  Startbyte[0]                    : '-'
                 *  Startbyte[1]                    : '+'
                 *  Nachrichtenlänge[2]             : 0..255
                 *  Anzahl Nutzdaten[3]             : 0..255
                 *  Daten Type[4]                   : 0..6
                 *  Nachrichten Identifikation[5]   : 0..255
                 *  Funktionsrückgabe Code[6]       : 0..255
                 *  Checksumme[7]                   : 0..255
                 *  Nutzdaten[8..n]                 : 0..255
                */
    
                Thread.Sleep(10);
    
                /*  Empfangene Daten abholen
                */
                try
                {
                    Length += Client.Read(buffer, Length, 250);
                }
                catch { }
    
                /*  Kommando Start Parsen
                 *  Rückgabewert: - 1 = Kein Start gefunden..
                */
                int index = Parser.ParseStart(buffer);
                if (index != -1)
                {
                    /*  Anzahl der zu empfangenen Bytes auslesen
                        * HIER WIRD NOCH KEIN CRC BERECHNET!
                        * Es könnten Übertragungsfehler nicht erkannt werden..
                    */
                    BytesToReceive = buffer[index + (byte)Cmd.Communication_Header_Enum.CMD_HEADER_LENGHT];
                }
    
                /*  Wurden alle Bytes empfangen?
                    *  Wenn nicht, direkt wieder raus hier!
                */
                if (Length < BytesToReceive)
                {
                    return;
                }
                else
                {
                    Length = 0;
                    BytesToReceive = 0;
                }
    
                /*  Kommando untersuchen..
                */
                Parser.Parse(buffer, ref Cmd.CommandoParsed);
            }
    
     
  2. addi

    addi Mitglied

    Registriert seit:
    2. September 2013
    Beiträge:
    107
    Zustimmungen:
    4
    Punkte für Erfolge:
    18
    Sprachen:
    BascomAVR, C, Assembler
    Hmmm...wo/wie wird der com port konfiguriert? Timeoutparamer setzen und einen rückgabewert bekommen.
    73 addi
     
  3. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.282
    Zustimmungen:
    8
    Punkte für Erfolge:
    38
    Sprachen:
    C, C#
    Hey Addi,

    ich arbeite ohne Timeout da die Daten im Event asynchron eingelesen werden.
     
  4. TommyB

    TommyB Premium Benutzer

    Registriert seit:
    17. Mai 2010
    Beiträge:
    1.726
    Zustimmungen:
    59
    Punkte für Erfolge:
    48
    Sprachen:
    Assembler, LunaAVR, VB.Net, Python, C#
    Sehr instabiles Konstrukt, merkste ja selber. Was ist wenn dein Length über Buffer.Length liegt? Crash.
    Was passiert wenn Length bereits auf 490 steht, Buffer.Length aber nur 500 Bytes groß ist? Du liest nur maximal 10 Bytes ein. Fragmentierung.
    Was passiert wenn dein Datenpaket was du haben willst 17 Bytes lang ist, du aber 19 empfängst? Ist ja ein Paket empfangen worden, also machst du n Buffer Reset, löscht also die 2 zu viel empfangenen Bytes.
    Dazu weiß ich nicht wie lange der buffer, also die alten Daten darin, gültig sind.

    Dein Problem wird sein, du erwartest (jeder [] Block ist ein Read):
    [12345678] [12345678]
    Du empfängst aber:
    [1] [2345] [6781] [23] [456] [78]
    Die 1 wird entfernt, also arbeitest du weiter mit:
    [23] [456] [78]
    was eine Protokollverletzung ist.

    Daher: Vernünftig sammeln und dann auswerten. Dafür wären Stichworte FiFo Buffer, RingBuffer, zur Not auch ne List(Of Byte).
     
  5. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.282
    Zustimmungen:
    8
    Punkte für Erfolge:
    38
    Sprachen:
    C, C#
    Du hast natürlich in allen Punkten recht.
    Habe ein wenig was angepasst. Jetzt funktioniert es einwandfrei. Die Pakete kommen an wie es soll.



    CodeBox C und C++
            private static int BytesIsReceive = 0;
            private static uint BytesToReceive = 0;
            private static byte[] buffer = new byte[256];
            public void Client_DataReceived(object sender, SerialDataReceivedEventArgs e)
            {
                /* Protokoll
                 *
                 *  Startbyte[0]                    : '-'
                 *  Startbyte[1]                    : '+'
                 *  Nachrichtenlänge[2]             : 0..255
                 *  Anzahl Nutzdaten[3]             : 0..255
                 *  Daten Type[4]                   : 0..6
                 *  Nachrichten Identifikation[5]   : 0..255
                 *  Funktionsrückgabe Code[6]       : 0..255
                 *  Checksumme[7]                   : 0..255
                 *  Nutzdaten[8..n]                 : 0..255
                */
                /*  Empfangene Daten abholen
                */
                try
                {
                    BytesIsReceive += Client.Read(buffer, BytesIsReceive, Client.BytesToRead);
                }
                catch
                {
                    return;
                }
    
                /*  Kommando Start Parsen
                 *  Rückgabewert: - 1 = Kein Start gefunden..
                */
                uint HeaderIndex = Parser.ParseStart(buffer);
                if (HeaderIndex >= 0)
                {
                    /*  Anzahl der zu empfangenen Bytes auslesen
                        * HIER WIRD NOCH KEIN CRC BERECHNET!
                        * Es könnten Übertragungsfehler nicht erkannt werden..
                    */
                    BytesToReceive = buffer[HeaderIndex + (byte)Cmd.Communication_Header_Enum.CMD_HEADER_LENGHT];
                }
                /*  Wurden alle Bytes empfangen?
                    *  Wenn nicht, direkt wieder raus hier!
                */
                if (BytesIsReceive < BytesToReceive)
                {
                    return;
                }
                if (BytesIsReceive == BytesToReceive)
                {
                    /*  Kommando untersuchen..
                    */
                    int ParserResult = Parser.Parse(buffer, ref Cmd.CommandoParsed);
                    //WriteDebugBuffer(buffer, (int)BytesToReceive, BytesIsReceive, ParserResult);
                    DataReceivedEventFunc(buffer,BytesToReceive);
                    BytesIsReceive = 0;
                    BytesToReceive = 0;
                }
                else if (BytesIsReceive > BytesToReceive)
                {
                    BytesIsReceive = 0;
                    BytesToReceive = 0;
                }
            }
    
     
  • Über uns

    Unsere immer weiter wachsende Community beschäftigt sich mit Themenbereichen rund um Mikrocontroller- und Kleinstrechnersysteme. Neben den Themen Design von Schaltungen, Layout und Software, beschäftigen wir uns auch mit der herkömmlichen Elektrotechnik.

    Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  • Coffee Time

    Unser makerconnect-Team arbeitet hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und unser eigener makerconnekt-Server regelmäßig gewartet wird. Wir nehmen das Thema Datensicherung und Datenschutz sehr ernst und sind hier sehr aktiv, auch sorgen wir uns darum, dass alles Drumherum stimmt!

    Dir gefällt das Forum und die Arbeit unseres Teams und du möchtest es unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft, unser Team freut sich auch über eine Spende für die Kaffeekasse :-)
    Vielen Dank!
    Dein makerconnect-Team

    Spende uns! (Paypal)
  1. Diese Seite verwendet Cookies, um Inhalte zu personalisieren und die Seite optimal für dich anzupassen. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden