Client/Server-Anwendung...
-
Hi,
Ich habe mir eine dialogbasierende Client/Server-Anwendung (basierend auf der Klasse CAsyncSocket) geschrieben, in der der Client dem Server Daten best. Grösse (z.B. 500 Bytes) sendet und der Server nach Empfang dieser Daten, sie wieder an den Client zurückschickt. Das Ganze habe Ich für TCP wie auch UDP realisiert und funktioniert auch wunderbar...- aber offenbar nur bis zu einer best. Grösse der zu sendenden bzw. zu empfangenen Daten.
D.h. wenn Ich beim Client den zu sendenden Puffer auf 5000 Bytes einstelle und beim Server den Empfangspuffer ebenfalls auf 5000 Bytes einstelle funktioniert das Ganze nicht wie gewünscht...

Hier ein bisschen Code (OnReceive() der Client-Applikation):
void CClientDlg::OnReceive() { m_iCounter++; // Datenpuffer dynamisch erzeugen m_pRecvBuf = new char[m_lSize]; int iRcvd, iBufSize; CString strRcvd; // Länge der Nachricht ermitteln iBufSize = m_lSize; // wurde TCP oder UDP ausgewählt? if (m_iSocketType == 0) { /** * TCP */ // Nachricht empfangen iRcvd = m_sConnectSocket.Receive(m_pRecvBuf, iBufSize); // Wurde etwas empfangen? if (iRcvd == SOCKET_ERROR) { } else { // Ende der Nachricht abschneiden m_pRecvBuf[iRcvd-1] = NULL; // CString für Ausgabe in Listenfeld formatieren strRcvd.Format("%d. %u Byte(s) sent and received in --> ???ms.", m_iCounter, m_lSize); // Nachricht in Listenfeld eintragen m_ctlRcv.AddString(strRcvd); // Variablen mit den Steuerelementen synchronisieren UpdateData(FALSE); } } else { /** * UDP */ ... } // überprüfen, ob beide Puffer (m_pTransBuf, m_pRecvBuf) // wirklich denselben Inhalt aufweisen bool bTest = FALSE; for (int i = 0; i < m_lSize; i++) { if (m_pTransBuf[i] != m_pRecvBuf[i]) bTest = TRUE; } if (bTest) AfxMessageBox("Sent and received data are not equal!"); }Dabei bezeichnet "m_pRecvBuf" folgendes:
// Datenpuffer dynamisch erzeugen m_pTransBuf = new char[m_lSize]; memset(m_pTransBuf, 'A', m_lSize); m_pTransBuf[m_lSize-1] = NULL;Muss Ich beim Verschicken grösserer Datenmengen etwas beachten?
Komisch ist auch, dass die MessageBox in der OnReceive()-Funktion meiner Client-Applikation bei einer Datenmenge von 5000 Bytes 2-mal auftaucht u. auch 2 Einträge in dem Listenfeld erscheinen. Bei einer Datenmenge von 10000 Bytes poppt die MessageBox 3-mal hoch u. auch 3 Einträge erscheinen im Listenfeld (statt wie gewünscht einem).Hoffe, Ich habe mich einigermassen verständlich ausgedrückt und wäre sehr dankbar, wenn mir jemand weiterhelfen könnte.
Danke
-Jackler
-
Hi
Ich weis leider nich so viel über AsyncSocket. Aber ich würds mit nem kleieneren Puffer versuchen. Bedenke die MTU. Das is ja n riesen packet.
Das kommt eh nur fragmentiert an. Vielleicht gibt es ja ne art max_buf der irgendwo definiert is !? Ich würd mir mal den Header ansehen.Sorry vielmehr kann ich nich helfen...
-
Hi,
Ich war eigentlich der Meinung, beliebig grosse Daten auf Basis von Sockets zwischen Client und Server hin- und herzuschicken (eben nur abhängig von der verwendeten Puffergrösse).
Ist es also nicht möglich z.B. zwischen Client und Server mal 10 MBs hin- und herzuschicken und dabei die Zeit zu messen (bis diese Daten wieder vollständig beim Client angekommen sind)?

Wäre super, wenn mir dazu jemand ein paar Hilfestellungen geben könnte...
Danke
-Jackler
-
Ich glaube, das TCp Protokoll spaltet die nachrichten (z.b. die 10MB) in viele Packete auf die dann alle einzeln verschickt werden, und vom server wieder zusammen gefügt werden. Somit kommen die Packete nicht alle gleichzeitig an sondern stück für stück und dann wird eben 3 mal oder mehr die OnRecieve aufgerufen. Also musst du die einzelnen packete erst wieder zusammenfügen. Korrigiert mich bitte, wenn ich da was falsch verstanden hab.
-
Hi <Daishy>,
dein Ansatz klingt sehr logisch...- das würde dann auch den mehrfachen Aufruf der OnReceive()-Funktion erklären.
Hast Du eine Idee, wo in meinem Programm Ich dann am besten die Zeitausgabe in das Listenfeld eintrage (bisher hab' Ich das in der Funktion OnReceive() gemacht) bzw. wie Ich jetzt meine Zeitberechnung (d.h. wie lange brauchen die Daten best. Grösse vom Client zum Server und wieder zurück) durchzuführen habe.
Die Zeitberechnung funktioniert folgendermassen:
long CClientDlg::queryPrecisionTime() { if (i_ResetPrecisionTime == 0) { i_ResetPrecisionTime = 1; QueryPerformanceFrequency(&uo_PerfCount.o_WinPart); l_PerfFrequ = uo_PerfCount.l_MyPart / 1000; QueryPerformanceCounter(&uo_PerfCount.o_WinPart); } ut_LargeInteger uo_perfCount; QueryPerformanceCounter(&uo_perfCount.o_WinPart); return ((long) ((uo_perfCount.l_MyPart - uo_PerfCount.l_MyPart) / l_PerfFrequ)); }Beim ersten Aufruf liefert die Funktion "queryPrecisionTime()" NULL. Bei jedem weiteren Aufruf liefert sie die verstrichene Zeit seit dem ersten Aufruf in ms.
D.h. wie meinst Du das bzw. wie kann Ich das realisieren: "Also musst du die einzelnen packete erst wieder zusammenfügen....".
Vielen Dank
-Jackler
-
Eine andere Frage diesbezüglich...- kann mir jemand sagen, wie viele Byte(s) minimal bzw. maximal Ich in ein einziges IP-Paket schreiben kann?
Vielleicht hat jemand von Euch auch ein paar gute Links zu diesem Thema...

Danke schon mal
-Jackler
-
Hi Guys,
hab' mich nun selbst etwas schlau gemacht was die Packet-Grösse betrifft.
Packete bestehen aus einem Header- und einem Data-Field. Das Data-Field ist variabel, was die Grösse betrifft, jedoch mit einer Begrenzung, die MTU (maximum transfer unit) genannt wird. Die MTU beträgt bei Ethernet (wie Du völlig richtig geschrieben hast) 1500 Bytes. D.h. es können nicht mehr als 1500 Bytes an Daten in einem einzigen Packet übertragen werden...
Falls also die Länge einer Nachricht die 1500 Bytes überschreitet (MTU), so wird die Nachricht in mehrere Packete aufgeteilt.
Aber soweit Ich weiss, kümmert sich doch das Betriebssystem darum... d.h. die Lösung meines Problems liegt einfach nur darin, in der OnReceive()-Methode so lange zu bleiben (while(...)), bis auch wirklich alle Daten empfangen wurden...- und genau das weiss Ich ja (Client und Server vereinbaren zu Beginn die Grösse der zu versendenden Daten).
Hoffe, dass das nun endlich funktioniert...

Ciao
-Jackler