Sporadischer Programm absturzt nach Socket ::recv(...)



  • Ich hab mal ähnliche Probleme gehabt.
    Wie schon von @It0101 erwähnt, ein Protokoll mit Längenangabe ist sinnvoll.
    Zu beachten ist, dass es sich, auch wenn man Pakete bastelt, immer noch ein Stream gesendet und empfangen wird. Ich hatte mal das Problem, dass im Stream (der ja auch nur eine definierte Länge hat) der Anfang des zweiten Paketes enthalten war…
    Ich habe mir zuletzt damit geholfen, dass ich die Daten in einer lesbaren Form (XML) gesendet, und vor dem Senden vom Server in eine Datei gespeichert habe. Der Client hat die empfangenen Daten auch erst mal in eine Datei gespeichert. Nun konnte ich schon mal durch Vergleichen der Dateien einiges ermitteln.



  • @SoIntMan sagte in Sporadischer Programm absturzt nach Socket ::recv(...):

    int byteSize = ::recv(s_, buf, len, 0);

    Füge doch mal bitte den folgenden Code ein und prüfe das Ganze nochmals im Debug-Modus.

    int byteSize = ::recv(s_, buf, len, 0);
    assert(bytesize < len);
    assert(buf[bytesize] == 0);
    


  • @It0101 sagte in Sporadischer Programm absturzt nach Socket ::recv(...):

    Hast du die Möglichkeit, die Daten mal nicht zu verarbeiten ,sondern auf Clientseite das Empfangen zwar vorzunehmen, aber mit den Daten erstmal nichts weiter zu tun? Quasi Ausschlussverfahren.
    Und dann im Nachgang die "Verarbeitung" der Daten mal ohne Socket zu testen.

    das mach ich auch so, ich allociere nur den puffer (wie oben) und geben ihn wieder frei...
    nach dem Ausschluss-verfahren habe ich den ::recv gemockt und es lief.. alls würde die daten aus recv korrupt sing..
    aber jetzt wo ich schreibe, mache ich doch ein bissel verarbeitung.. das nehm ich mal raus

    @Helmut-Jakoby sagte in Sporadischer Programm absturzt nach Socket ::recv(...):

    Ich hab mal ähnliche Probleme gehabt.
    Wie schon von @It0101 erwähnt, ein Protokoll mit Längenangabe ist sinnvoll.
    Zu beachten ist, dass es sich, auch wenn man Pakete bastelt, immer noch ein Stream gesendet und empfangen wird. Ich hatte mal das Problem, dass im Stream (der ja auch nur eine definierte Länge hat) der Anfang des zweiten Paketes enthalten war…
    Ich habe mir zuletzt damit geholfen, dass ich die Daten in einer lesbaren Form (XML) gesendet, und vor dem Senden vom Server in eine Datei gespeichert habe. Der Client hat die empfangenen Daten auch erst mal in eine Datei gespeichert. Nun konnte ich schon mal durch Vergleichen der Dateien einiges ermitteln.

    ja ich versuche gerade die daten roh (ohne überlagertes framing etc. zu anylsieren)

    @Quiche-Lorraine sagte in Sporadischer Programm absturzt nach Socket ::recv(...):

    Füge doch mal bitte den folgenden Code ein und prüfe das Ganze nochmals im Debug-Modus.
    int byteSize = ::recv(s_, buf, len, 0);
    assert(bytesize < len);
    assert(buf[bytesize] == 0);

    leider kann ich nich debbuggen.. WinCE

    Aber ich könnte die App auch einfach mal wuf win32 kompilieen.. hmm;) und da debuggen..



  • @SoIntMan sagte in Sporadischer Programm absturzt nach Socket ::recv(...):

    leider kann ich nich debbuggen.. WinCE
    Aber ich könnte die App auch einfach mal wuf win32 kompilieen.. hmm;) und da debuggen..

    Ich frage mich welche Art von Daten (Binär, ASCII) du durch recv() empfängst.

    int Receive3(char* buf, int len)

    So ein char* kann leider viele Gesichter annehmen:

    • Binäre Daten
    • Nullterminierter String (String + '\0')
    • String Pool (String + '\0' + String + '\0' + '\0')

    Und wenn der buf Parameter der Receive3() Funktion ein nullterminierter String darstellen soll, so kann es unter gewissen Umständen zu einer fehlende Nullterminierung kommen. Und dann knallt es z.B. wenn du strlen(buf) aufrufst.


    Probiere doch mal ob du den Code geschickt unterteilen kannst, s.d. dieser auf einem Entwicklungsrechner läuft. Dann könnte man einen Stresstest probieren. Die Serverseite könnte man mittels einem einfachen C#/Python Programm simulieren.



  • Guten Morgen ..

    irgndwie habe ich das Gefühtl dass unter WinCE "ws2.lib" und unter Win32 "Ws2_32.lib" das verhalten unterscheidlich ist, da es bei gleicher verwendung von ::recv in wince crashed und in win32 nicht!?



  • Mal ne ganz dumme Überlegung: Wenn recv fehlerhaft wäre, wäre der Fehler nicht schon vor vielen Jahren aufgefallen? Der Fehler muss bei dir liegen. Irgendein Zeiger zeigt nicht wie er soll.



  • Ich weiß nicht, wie du die empfangen Daten verarbeitest oder wie diese gestaltet sind. Aber ich wage mich nochmal mit einer Vermutung raus (habe ich im vorherigen Post nur angedeutet), weil ich mich so an ein Phänomen erinnert fühle.

    Auch wenn von Streams gesprochen wird, wird der ab und an in Teilen übertragen; siehe "tcp packet size".

    Also unter dem einem Betriebssystem habe ich zwei "chunks" (jeweils mit eigenem Header wie Art und Größe der folgenden Daten) nacheinander losgeschickt und es kamen auch zwei IP-Pakete "nacheinander" mit jeweils einem "chunk" an.

    Unter dem anderen Betriebssystem habe ich auch zwei "chunks" nacheinander losgeschickt, und es kamen auch zwei IP-Pakete an, aber eben im ersten IP-Pakete der erste "chunk" und die ersten Bytes des zweiten "chunk".
    Das zweite IP-Paket hatte also nur den Rest des zweiten "chunks" und meine Anwendung hat das natürlich nicht verstanden, weil der Header des zweiten "chunks" nicht vorhanden war.

    Ich habe lange dran herumgedoktert, weil ich lange annahm, das meine "chunks" immer als ganzes beim Client ankommen, was sie ja auch im einem Betriebssystem getan haben. Ich dachte auch lange, dass ich durch das definieren der "tcp packet size" alles in der Hand habe. Stimmte aber im letzteren Fall nicht, das zweite Betriebssystem tat da was es wollte, bzw. sendete bzw. empfing wirklich einen Stream ggf. mit halben oder auch mit mehreren "chunks".

    Bitte entschuldige das krude Deutsch, aber ich wollte das IP-Paket und "mein Paket" verdeutlichen.



  • @SoIntMan sagte in Sporadischer Programm absturzt nach Socket ::recv(...):

    irgndwie habe ich das Gefühtl dass unter WinCE "ws2.lib" und unter Win32 "Ws2_32.lib" das verhalten unterscheidlich ist, da es bei gleicher verwendung von ::recv in wince crashed und in win32 nicht!?

    Weist was, wir probieren es mal auf die andere Weise.

    Probiere doch mal bitte, ob durch den folgenden Code der Fehler behoben wird

    int byteSize = ::recv(s_, buf, len - 1, 0);
    if (byteSize > 0)
      buf[byteSize] = 0;
    

    Ich gehe hier einfach mal davon aus, das du nullterminierte Strings einlesen möchtest und stelle deswegen explizit die Nullterminierung sicher.



  • @Quiche-Lorraine sagte in Sporadischer Programm absturzt nach Socket ::recv(...):

    Weist was, wir probieren es mal auf die andere Weise.
    Probiere doch mal bitte, ob durch den folgenden Code der Fehler behoben wird
    int byteSize = ::recv(s_, buf, len - 1, 0);
    if (byteSize > 0)
    buf[byteSize] = 0;

    Ich gehe hier einfach mal davon aus, das du nullterminierte Strings einlesen möchtest und stelle deswegen explizit die Nullterminierung sicher.

    Hi Danke für dein Engagement, aber leider nein, ich lese reine Binär daten:)

    ist der Buffer den ich ::recv übergebe kleiner als die Daten welche im tcp stack hängen dürfte es ja kein problem geben,
    ist der Buffer größer als die im verfügbaren daten, dann bekomme ich ja die anzahl der gelesen bytes zürück .. d.h. es "müsste" ja gehen... außer ich hab ein mem-bock drin, und win32 is da entspannter als CE (wobei wince6 geh, wince8 nicht)



  • Du musst lernen wie man WinCE Programme remote debuggt


Anmelden zum Antworten