Socket: Übertragung "Ruckelt"
-
Hmm, guter Einwand.
Also theorethisch warten dann beide auf sich gegseitig und das Programm würde komplett hängen. Also Beispiel:
Server schickt Bild, wartet auf OK;
Client bekommt Bild, sendet OK, welches verloren geht.Server wartet, also immernoch auf das OK;
und Client wartet auf das nächste Paket (die Buffergröße für das darauffolgende Bild)Also beide würde dann bis zum timeout warten, bzw. bis die Verbindung unterbochen wird.
Das werde ich noch anpassen. Hat aber leider nix mit dem Problem, des Hängen zutun. Denn mein Programm ist so ausgelegt das wenn die Verbindung unterbrochen würde, das Programm sich wieder beendet. Und das tuts ja nicht. Es hängt einfach für ne halbe Sekunde.... Als, wenn er darauf Wartet die minimal Send-Window größe zusammen zukriegen und dann erst das Paket verschickt.
Ich werde jetzt mal protokoll führen. Wie lange jeder Transfer dauert und was das für ein Paket ist. Vlt. hilft mir das ja weiter.
-
Ja, sehe gerade, dass du TCP benutzt.
Moegliche Ursachen: Virenscanner, Torrent-Client, Festplattenzugriffe, ...
-
Okay, ich habe jetzt ein Protokoll erstellt.
Jetzt weiss ich das der Hänger immer in folgender Situation auftritt:Alle 5 Bilder wird ein kleiner String vom Klienten an den Server geschickt. In diesem String stehen die Kameraeinstellungen. Der String sieht so aus:
stringstream ss; ss << "# DesparityMax\n" << myParam->maxDisparity << "\n" << "# DesparityMin\n" << myParam->minDisparity << "\n" << "# Narrow 0 Wide 1\n" << myParam->CamSetting << "\n" << "# Solution 0 = 320x240, 1 = 640x480, 2 = 1280x960\n" << myParam->choosenResolution << "\n" << "# TotalColor 240 - 360\n" << myParam->TotalColorSpread << "\n" << "# Use Compression 0 = None, 1 = Difference, 2 = Zip, 3 = ZipAndDifference\n" << myParam->usedCompression;
Also nix weltbewegenes.
Laut Protokoll dauert das Senden der Länge des Strings (also nicht der String selber) auf Clientseite 2.73054e-006s, der Empfang auf Serverseite jedoch ~0,2 Sekunden.
Woran kann das liegen?EDIT: Firewalls, Virenscanner sind deaktiviert, Festplatte ist eine schnelle SSD
-
Du könntest mittels Wireshark deinen Netzwerkverkehr auslesen und schauen, ob es dort Verzögerungen gibt.
Aber schau mal hier:
http://support.microsoft.com/kb/214397/en-us
Vielleicht liegt es daran..Du solltest die Winsock 2,2 Version aufrufen.
Und ich lege dir vorab http://msdn.microsoft.com/en-us/library/windows/desktop/ms740141%28v=vs.85%29.aspx ans Herz. Die wird Dir sicherlich noch nützlich sein...
//Edit:
typedef struct _SYSTEMTIME { WORD wYear; WORD wMonth; WORD wDayOfWeek; WORD wDay; WORD wHour; WORD wMinute; WORD wSecond; WORD wMilliseconds; } SYSTEMTIME, *PSYSTEMTIME; SYSTEMTIME SysTime; SYSTEMTIME SysTime2; GetLocalTime(&SysTime); recv(..,..,..,..); GetLocalTime(&SysTime2); //Späterer Zugriff über die SysTime bzw. SysTime2 //Member. // Da bekommst du die Uhrzeit des Rechners bis Millisekunden. // Ich würde es jeweils vor und nach dem send bzw. recv anzeigen, da du somit //mittels der Differenz die benötigte Zeit sehen kannst.
-
Danke für den Tip (http://support.microsoft.com/kb/214397/en-us)
Tatsächlich hat der kleine String den durchsatz halbiert und mit deaktivierten Neagle Algoritmus, konnte der Durchsatz wieder verdoppelt werden.
Danke nochmal!
PS:
Ich hatte für die Zeitmessung die QueryPerformanceCounter() Funktion der Winapi genommen.Aber gut zu wissen das Systemtime auch die Millisekunden speichert.
-
Ein Problem mit deinem Code ist, dass recv() nicht so funktioniert wie du meinst.
Liest nochmal die Doku nach, vielleicht geht dir dann ein Licht auf.
-
recv() muss in einer Schleife aufgerufen werden.
Ein guter Tip... überprüfe die Rückgabewerte! Das sollte man immer tun...
-
hustbaer schrieb:
Ein Problem mit deinem Code ist, dass recv() nicht so funktioniert wie du meinst.
Liest nochmal die Doku nach, vielleicht geht dir dann ein Licht auf.Hallo,
ich denke du meinst damit das die Recv() nicht immer alle Bytes abholt und deshalb in einer Loop geholt werden sollte. Das Passiert bei mir allerdings beim großen Datenpaket (dem umkomprimierten Bild). Einzig dem kleinem Paket (in dem nur die Dateigröße des Bildes steht) wird bei mir nicht in einer Loop geholt.Ich bin gerade dabei das ganze System anders aufzubauen. Meine Überlegung ist nun nicht mehr jeder Nachricht zu quittieren sondern in den Paketen Trennbytes einzufügen und den Klienten dann immer nur bis zu den Trennbytes in der Schleife empfangen zu lassen. Während der Sender immer neue Bilder losschickt.
Kann es bei diesem Asynchronen Verhalten dazu kommen das der Kanal "zugestopft" wird wenn der Sender immer Daten verschickt und der Empfänger nicht schnell genug liest? Ich denke ja schon. Aber wie sollte ich das dann verhindern? Also vlt. ein semi-synchrones System? Der Server haut meinetwegen 20 Bilder in den Kanal und wartet dann erstmal auf eine Antwort vom Klienten bevor er die nächsten 20 Bilder losschickt?
Bin für Tips gerne offen
Danke nochmal für die super Hilfe hier.
Echt super Forum!
-
Genau, was passiert eigentlich, wenn der Sender zB. 1 MB Upload hat, der Empfänger aber nur 128 kB Download?
Sender sendet wie verrückt (kann er ja, oder? Weiß ja nichts vom Downloadspeed des Empfängers), wo landen die ganzen Daten?
-
-
Bzw. wenn Pakete verloren gehen (was passiert wenn der Sender zu schnell sendet), dann bekommt das der Sender ja auch mit - der Empfänger bestätigt diese Pakete dann ja nicht.
In dem Fall drosselt der Sender auch die Geschwindigkeit.