Programm reagiert beim Ausführen anders als beim Debuggen
-
Hallo zusammen,
ich versuche momentan einen ICQ-Client zu programmieren. Dabei beziehe ich mich auf das Oscar Protokoll. Bin grad dabei das Login umzusetzen, allerdings habe ich das Problem, dass wenn ich das Programm ausführe, nicht alle Methoden ausgeführt werden. Sprich, im Debugmodus tut es wie es soll und wenn ich dann auf STRG + F5 drücke, gibt die Konsole was ganz anderes aus.
Ich versende z.B. zum Login via Socket eine Login-Anfrage an den ICQ-Server, dann krieg ich ein Datenpaket vom Server zurück, aus dem ich dann die Login-Infos wie ip, port und Cookie auslese und dann an den BOS-Server schicke... Auf der Konsole gebe ich dann aus, wieviele Bytes versendet bzw. empfangen wurden und genau da werden dann die Unterschiede zwischen Debug- und Ausführmodus deutlich. Im Debug-Modus (F5) sieht die Konsolenausgabe wie folgt aus:Beim Einlogen wurden 140 Bytes an den Server versandt.
Es wurde eine Antwort mit 314 Bytes vom Server empfangen.
Es wurde das Cookie mit 270 Bytes gesendet.
Es wurde nichts vom BOS-Server empfangen. Error-Code 10053Die Fehlermeldung mit dem Code 10053 kommt nur weil, beim Debuggen zuviel Zeit verstreicht, bis meine Anwendung die Daten sendet. Das ist also soweit OK und nicht verwunderlich.
Wenn ich dann das gleiche Programm direkt mit (STRG+F5) ausführe, kommt folgende Ausgabe auf der Konsole:
Beim Einlogen wurden 140 Bytes an den Server versandt.
Es wurde eine Antwort mit 10 Bytes vom Server empfangen.
Es wurden 304 Bytes vom BOS-Server empfangen.Die Konsolenausgabe darüber mit wievielen Bytes das Cookie gesendet wurde wird dabei ganz unterschlagen und auch die Byteangaben stimmen nicht mit denen vom Debuggen ein...

Woran kann das liegen?
Hab keine Idee, was ich da ändern müsste... damit beim Ausführen auch alles so ausgeführt wird, wie beim Debuggen...Hat jemand vielleicht eine Idee, was ich da tun kann, oder wo der Fehler liegen könnte...?
-
recv in einer Schleife aufrufen
-
recv() ist doch blockierend und wartet normalerweise solange bis die gesamte Nachricht empfangen wurde? Von daher brauch man doch keine Schleife?
Und wenn doch, wie lang wartet recv() in der Schleife?
-
recv() ist doch blockierend und wartet normalerweise solange bis die gesamte Nachricht empfangen wurde?
Bei TCP nicht. Nur bei UDP. recv kehrt zurück sobald mindestens 1 Byte da ist.
-
Meinst du so etwa:
for(;;) { data_size = recv(socket, buffer, len, 0); }Aber wie komm ich dann wieder raus? vorallem wann oder woher weiss ich, dass alle Bytes empfangen wurden?
-
ungefähr so: http://www.c-plusplus.net/forum/viewtopic-var-t-is-115628-and-start-is-9.html
wenn das paket immer eine feste größe hat dann
char buffer[314]; recv_all(sock, buffer, sizeof(buffer));oder wenn die paket-größe irgendwo am anfang des pakets steht
int packetSize; recv_all(sock, (char*)&packetSize, sizeof(packetSize)); char* pBuffer = new char[packetSize]; recv_all(sock, pBuffer, packetSize);
-
Cool, danke
Es hat geholfen 
-
Habe wieder ein Problem mit der recv() Methode. Diesmal ist nicht ersichtlich, wieviele Bytes ich vom Server empfangen werde. Jedesmal wenn ich dann recv() nach der genannten Methode aufrufe, kommt der Fehler-code: 10053. Und wenn ich dann recv() ohne Schleife aufrufe, empfange ich 10 Bytes, was allerdings zu wenig sein dürfte...

Meine Frage ist nun, was kann ich tun, wenn die Grösse des empfangenen Datenpakets unbekannt ist?

-
Fehler 10053:
An established connection was aborted by the software in your host computer, possibly due to a data transmission time-out or protocol error.die Verbindung is dir gerade Verlustig gegangen. Hab deine ganze Sache net beobachtet und auch net geschaut was du wie machst, aber das sieht mir aus wie ne UTP verbindung und die is nun mal Verbindungslos, also kannst du nur neu Anfragen. Wobei ich net verstehe warum es keinen Header gibt.
na wie auch immer wenn ich daneben liegen sollte, dann vergiss was ich geschrieben habe
-
Also es ist eine TCP-Verbindung. Einen Paket-Header gibts auch, das 5. und 6. Byte geben die Paketgrösse an. Ich habs auch damit versucht, allerdings scheint die angegebene Datengrösse nicht zu stimmen.

Es fehlen ein paar Byte und dann kommt die Fehlermeldung 10055, weil ich zuwenig Buffer-Platz angebe.
Das Datenpaket sieht wie folgt aus:2A 02 3D FE 00 22 00 01 00 03 00 00 82 95 E5 7A 00 01 00 02 00 03 00 04 00 06 00 08 00 09 00 0A 00 0B 00 0C 00 13 00 15Die ersten 6 Bytes sind der Header und 00 22 geben die Grösse an, wobei die nicht stimmt, wenn man nachzählt, deshalb bin ich auch etwas verwirrt... wie ich die Grösse auslese, dass es passt...
-
hm, sorry, die grösse stimmt doch... ist ja hex... ich stand grad ziemlich aufm Schlauch

-
Es funktioniert trotzdem nicht. Immer wieder kommt der Fehler-Code: 10053

Ich poste am Besten mal den Quellcode:int Oscar_ICQ::recvSupportedServices() { /*Buffer mit 0 belegen*/ for(int i = 0; i < BUFFERSIZE; i++) { recvBuffer[i] = '\0'; } /*Vorerst Länge auf 16 setzen*/ int len = 16; int r = 0; int x = 0; /*Die ersten 16 Bytes empfangen*/ while(r < len) { x = recv(con->getSocket(), recvBuffer + r, len - r, 0); if(x == SOCKET_ERROR) return -1; r += x; } /*Grösse des Buffers aus Feld 4 und 5 auslesen*/ char val1 = recvBuffer[4]; char val2 = recvBuffer[5]; len = binary(val1, val2); /*Berechnung der Grösse*/ r = 16; int curr = 0; x = 0; /*Im Buffer ab der Stelle, an der aufgehört wurde die restlichen Bytes lesen*/ while( curr < len) { x = recv(con->getSocket(), recvBuffer+r+curr, len - r, 0); if(x == SOCKET_ERROR) return -1; curr += x; }/*Empfangene Bytesgrösse zurückgeben*/ return data_size = curr+16; }
-
x = recv(con->getSocket(), recvBuffer+r+curr, len - r, 0);Kann nicht gehen! Du berücksichtigst curr nicht und liest evtl. damit zuviele Daten.
-
also dann so:
x = recv(con->getSocket(), recvBuffer+r+curr, len - r [b] - curr[/b], 0);
-
Habs geändert, aber es liegt nicht daran. Es scheitert schon vorher, beim Einlesen der ersten 16 Bytes, da gibt die recv()-Funktion -1 zurück.
-
Hm, keiner eine Idee, woran es noch liegen könnte. Hab schon alles mögliche ausprobiert. Es werden immer nur 10 Bytes empfangen und die beinhalten nicht die Informationen über den Service. Praktisch bekomme ich nur den Header mit 6 Bytes und die Protokoll-Versions-Nr. mit 4 Bytes. Danach kommt nichts mehr und wenn ich den Puffer grösser mache, gibts die Fehlermeldung 10053. Habe echt keine Idee, was ich noch probieren könnte.

-
Dann werden wohl nicht mehr als 10 Bytes gepostet oder das Protokoll ist anders als Du es vermutest.
-
Hm, das kann natürlich sein, dass das Protokoll anders ist. Die Spezifikations-Erklärung, die ich herangezogen habe, ist auch schon ein paar Jährchen alt. Wäre natürlich möglich, dass sich da einiges geändert hat, oder dass die ICQ-Versions-Nr., die ich an den ICQ-Server sende, zu alt ist und deshalb keine möglichen Service-Informationen zugeschickt werden. Scheint also kein C++ spezifisches Problem zu sein. Nochmal Danke für die Hilfe.
