CAsyncSocket



  • Hallo,

    ich arbeite gerade an einem Projekt, bei dem ich Positionsdaten via Socket-Verbindung an einen anderen Rechner versende. Dazu nutze ich CAsyncSocket. Zum Testen habe ich eine ganz einfache Dialoganwendung gebaut, die als Server und Client agieren, sich verbinden und einzelne Werte übertragen kann. Soweit standard! Nun habe ich mir einen Timer gebastelt, der sicherstellt, dass alle 40 millisec ein Wert übertragen wird und beim Empfänger als Iteration angezeigt wird (so werden später die Pos-Daten übertragen).
    Lässt man das ganze lokal auf einem Rechner ablaufen passt alles. Laufen die Anwendungen auf verschiedenen Rechnern (GigE-Verbindung), dann springt die Iterations-Anzeige beim Empfänger! Die aktuelle Durchlaufnummer gebe ich als Static-Text aus und diese springt dann immer um ca 7 weiter und ruckelt dementsprechend. Meine erste Vermutung war, dass einfach nicht mehr Werte empfangen werden: das ist jedoch nicht so, denn wenn man sich die Anzahl der Receive-Aufrufe ausgeben lässt, dann springt diese parallel zur Iteration!

    Um die Verwirrung komplett zu machen: sobald man diese Dauerübertragung von beiden Seiten ausführt, läuft alles einwandfrei!!

    Ein Sleep(...) nach dem Empfangen bringt etwas Besserung bei der einseitigen Dauerübertragung, aber dennoch läufts nicht rund.

    Hat jemand eine Idee, woran dieser Übertragungsfehler liegen könnte? Danke!

    Grüßchen lola



  • Windows ist kein EchtzeitBS. Du kannst Dir also nicht sicher sein das es 40ms sind.
    Weiters braucht auch der andere Rechner Zeit für sich selbst.
    Und dann noch Deine Verarbeitungszeit.
    Zu Sleep in Threads und warum manches besser läuft gibt es hier schon einige Postings.
    So wie es aussieht sendest Du dauernd und dein Thread braucht 100% CPU-Zeit.



  • Die 40 milisec habe ich ausgiebig getestet: das passt! Folgerichtig sende ich nicht dauernd. Die CPU-Auslastung liegt bei 0%.
    Trotzdem danke für die Anregungen. Das Unverständliche an der Sache ist, dass sobald beide Rechner gleichzeitig alle 40 millisec Senden es wunderbar funktioniert.

    Also werde ich es nun vorerst so implementieren, dass der eine Rechner Nonsence zurücksendet. Nicht gerade ne saubere Lösung. Sollte jemand noch eine Idee haben, oder es kurz selbst testen wollen, wäre ich sehr dankbar.

    Aufbau:

    CAsyncSocket m_ConnectSocket;
    CAsyncSocket m_ListenSocket;
    CString m_ip;
    int m_port;
    UINT_PTR m_Timer;
    
    ...
    
    if(m_server == false){
       m_ConnectSocket.Create();
       m_ConnectSocket.Connect(m_ip, m_port);
    }
    if(m_server == true){
       m_ListenSocket.Create(m_port);
       m_ListenSocket.Listen();
    }
    
    ...
    
    m_Timer = SetTimer(1,32,0); // bei meinem Rechner ergibt das ca. 40 milisec
    
    ...
    
    OnTimer(UINT_PTR nIDEvent){
       static int test = 1;
       test++;
       m_ConnectSocket.Send((char*)&test,sizeof(test),0);
       CDialog::OnTimer(nIDEvent);
    }
    
    ...
    
    m_ConnectSocket.Receive((char*)&test,sizeof(test));
    


  • Ich dachte der eine Sendet und der andere Empfängt?????

    Wenn DU AsyncSockets verwendet das bekommt der Empfänger(Server) immer eine Nachricht wenn Daten anliegen.
    Wozu solltest Du dann von Server wieder an den Client senden?



  • Ich habs doch oben ausführlich beschrieben:
    - wenn EINER sendet und der ander empfängt, dann gibts Probleme. Zum Testen versendet der Sender einen ansteigenden Zähler(1,2,3....). Dieser wird beim Empfänger entgegengenommen und als Static-Text dargestellt. Dabei ergeben sich deutlich sichtbare Sprünge/Ruckler (z.B. 1,7,12,20,....). Zeitlich passt es aber dennoch (nach einer Min wird 1500 angezeigt: korrekt). Lasse ich mir die Anzahl der Receive-Aufrufe beim Empfänger in einem separaten Static-Text anzeigen, so ergeben sich die gleichen Sprünge!!
    - nur zum Testen (worans liegt) habe ich den anderen Rechner auch senden lassen. Es senden also BEIDE Rechner und empfangen gleichzeitig! Wenn beide senden passt es, d.h. die Zähler werden kontinuierlich hochgezählt und ohne Aussetzer dargestellt.

    Meine Vermutung lautet nun: wenn es funktioniert wenn beide senden, sollte es auch möglich sein, dass es klappt wenn nur einer sendet!



  • Wie ließt Du den die Daten aus dem Buffer.
    Wenn Du sendest heißt das nicht das es sofort gesendet wird.

    sendest Du ein 2tes Mal kann es sein das es das beide gleichzeitig als ein Packet rausgehen.



  • Auslesen:
    CAsyncSocket::OnReceive():

    int test;
    m_ConnectSocket.Receive((char*)&test,sizeof(test));
    

    Zum Testen übertrage ich nur ein INT.



  • wenn du aber 2 in kurzem abstand sendest können bei gleichzeitig im buffer landen.
    gibt bei Windows sogar eine Begriff dafür der mir aber jetzt nicht einfällt.
    Vor 3 oder 4 Jahren war das mal Thema hier.



  • Wenn ich dich richtig verstanden habe, dann gehst du davon aus, dass bei einseitiger übertragung (bei diesem zeitl. Abstand) immer mehrere Werte kombiniert versendet werden.
    Könnte die Ursache sein, sofern beim Empfangen dieses "Werte-Pakets" die Receive-Funktion mehrmals (für jeden Wert) aufgerufen wird.

    Gibts Möglichkeiten dies zu umgehen?



  • Mach doch mal eine Debug und schaue nach



  • Guck mal wie man den "Nagle algorithm" ausstellt, der ist verantwortlich für dein "Problem" 😉


Log in to reply