2016-04-09 13 views
4

Ich habe vor kurzem Code für ein benutzerdefiniertes serielles Kommunikationsprotokoll geschrieben. Was ich gemacht habe, war, dass ich einen Teil (8/16 Bit) der Empfangsdaten verwendete, um anzuzeigen, wie groß die Rahmengröße ist. Basierend auf diesen Daten erwarte ich , dass keine Daten folgen. Ich benutze Crc, um einen Rahmen zu akzeptieren oder abzulehnen. Aber ich werde nicht in der Lage sein, die Framelänge Daten in die Crc, da auf der Empfängerseite sollte ich wissen, wie viele Daten zu erwarten, bevor ein Frame verarbeiten.Wie verhindert man Pufferüberlauf/Array-Überlauf?

Das Problem, das ich konfrontiert wurde, ist gelegentlich diese Rahmenlänge Daten wird beschädigt und es täuscht den Empfänger zu empfangen, dass viele Bytes, während die empfangende Array-Größe ist viel weniger als das. Dies korrumpiert viele kritische Systemvariablen, die in den aufeinanderfolgenden Speicherstellen vorhanden sind.

Wie verhindere ich, dass ein Pufferüberlauf auftritt? Meine Gedanken dazu 1) Verwerfen Sie die Framelayness Daten, wenn es einen bestimmten Wert überschreitet. 2) Verwenden Sie einen Datentyp, der die max. Wie die Verwendung einer Abkürzung, die den Bereich des Array-Index auf 256 Speicherpositionen beschränkt, und einen Puffer mit 280 Byte erstellen. 3) Speicher an einem separaten Ort zuweisen, so dass er die kritischen Systemvariablen nicht beeinflusst.

Eine Sache, die ich verwendete, um zu verhindern, in der Empfangsschleife stecken zu bleiben, ist die Verwendung eines Timeouts. Aber ich habe diesen Aspekt des Problems übersehen. Es sieht mir sehr danach aus, ob es Zeit ist, das Problem zu bestätigen und zu reproduzieren, da Code somit Teil eines größeren Systemcodes ist und ich hier kein Experte bin.

Allgemein, wie man diese Art von Problemen sicher behandelt?

Auch: Was sind allgemeine Überlegungen oder Standardverfahren bei der Verwendung eines Arrays, um ein Überlaufen zu verhindern?

+0

Entschuldigung, wenn ich einige Terminologien missbraucht habe. – seetharaman

+0

Ich würde sagen 2) ist die richtige Antwort. (Obwohl 'short' 2 Byte ist und was Sie wollen, ist ein Ein-Byte-Wert.) – user3386109

+0

Ich verstehe nicht, wie die Daten der Rahmenlänge, die beschädigt werden, den Empfänger in einen Pufferüberlauf täuschen könnten. Sicherlich liest der Empfänger genau die Anzahl der Bytes, die er erwarten soll (oder versucht, dies zu tun), und es liegt im Ermessen des Empfängers, sicherzustellen, dass er einen ausreichenden Puffer dafür hat, selbst wenn die empfangene Rahmengröße falsch ist. –

Antwort

1

Es gibt viele Dinge, die verwendet werden können, um dieses Problem zu minimieren, aber es gibt keine One-Size-Fit-All-Lösung für diese im Allgemeinen. Sie müssen Entscheidungen treffen und verstehen, was passiert, wenn etwas schief geht und Ihr System damit umgehen kann.

Sie müssen herausfinden, was genau für Ihr System am besten passt. Wenn Sie beispielsweise nie erwarten, dass eine Nachricht größer als 256 ist, dann deklarieren Sie die Größe Ihres Puffers als 0xFF und den Index Ihres Puffers als uint8_t. Sie können ihn nie überschreiten, indem Sie ein Byte nach dem anderen einfügen erreichen Sie niemals 256 und einen Überlauf zurück auf 0. Die Kehrseite davon ist natürlich, wenn dies passiert, überschreiben Sie einige der empfangenen Daten, aber die CRC-Prüfung sollte in den meisten Fällen Fehler aufdecken.

Eine andere Sache, die Sie tun können, ist die Datenlänge mit dem Puffer max zu vergleichen und nicht die Nachricht zu speichern, wenn es Ihren Puffer überschreitet. Sie würden also alle Nachrichten ablehnen, deren Datenlänge zu groß und zu groß ist, aber keine Daten speichern. Offensichtlich, wenn die Datenlänge oft beschädigt wird, haben Sie eine Menge Probleme damit.

Um ehrlich zu sein, ist die beste Methode, Ihr benutzerdefiniertes serielles Kommunikationsprotokoll zu überdenken. Es hört sich nicht so an, als würde es die Fehler, denen Sie begegnen, sehr gut treffen. Sie können Synchronisierungsbytes am Anfang und am Ende Ihrer Nachricht haben, um sicherzustellen, dass Sie tatsächlich gute Daten und CRC die gesamte Nachricht erhalten, kein Problem und definieren Sie maximale Datenpaketgrößen, die über die Leitung gehen und signalisieren, wie viele Pakete es sind erhalten. Wenn das Kommunikationsprotokoll nicht sehr gut ist, müssen Sie es von Grund auf neu überdenken.

+0

Ich werde versuchen mit Unit8. Ich verwende bereits Sync-Bytes am Anfang des Frames. Erst nachdem ich die Sync-Bytes gefunden habe, erhalte ich diese Frame-Size-Daten. Es scheint, als ob Datenkorruption in einem zufälligen Byte (s) in einem Rahmen auftritt und die anderen Bytes scheinen in Ordnung zu sein. – seetharaman

1

erste, Überprüfung auf Rahmenfehler, prüft auf Paritätsfehler

Sekunden, überprüft die Größe der Datengröße. Wenn zu groß oder zu klein, lehnen Sie den gesamten Datenblock ab

+0

Ich verwende eine Kopfzeile, um den Anfang des Rahmens und für die Bitpositionierung zu erkennen. Da die Paarung nicht UART ist, wird das Berechnen in SW ein Overhead sein. Überprüfen Sie die Größe des Rahmens und die Ablehnung funktioniert möglicherweise. – seetharaman