[WINSOCK] send() verhält sich erwas unlogisch



  • danke das du so schnell geantwortet hast.

    habe die funktion nun etwas umgeschrieben jedoch gleicher fehler wie vorher oder hab ich deinen tipp einfach nur falsch verstanden ? 😃

    habe jetzt zusätzlich das feld länge eingefügt.
    vorm versenden wird die länge des strings ermittelt und danach '\0' dran gehangen.

    hat auch keinen einfluss.

    was ich unbedingt sagen muss, ES FUNKTIONIERT ( schon immer ) im netzwerk, aber über das inet nicht.

    void   SendUserListe( Liste *pRoot , int nSocket )
    {
        int nLaenge = 0;
        Liste *pTail = pRoot;
        char szNicknameBuffer[30] = { 0 };
    
        while( pTail != NULL )
        {
    
            wsprintf( szNicknameBuffer , "02%s", pTail->szNickname );    
            nLaenge = strlen( szNicknameBuffer );
            szNicknameBuffer[nLaenge] = '\0';
            //MessageBox( NULL , szNicknameBuffer , NULL, NULL );
            send( nSocket , szNicknameBuffer, strlen( szNicknameBuffer ) , 0 );
    
            pTail = pTail->pNext;
        }
    }
    

    mfg richi 😃



  • Du hast ihn falsch verstanden 😉
    Zumindest hat sich an der Schleife nichts geändert!

    Versuch es mal so:

    nLaenge=wsprintf(szNicknameBuffer, "02%s", pTail->szNickname);
    send(nSocket, szNicknameBuffer, nLaenge, 0);
    

    Beachte, dass (gerade übers Internet) deine Netztwerkkarte zu sendende Daten in einem Buffer speichert und dann alle mit einmal sendet. Dem entsprechend kommen sie auch auf einmal an.

    [ Dieser Beitrag wurde am 05.01.2003 um 22:12 Uhr von D@niel $chumann editiert. ]



  • hallo,
    habe es mal auf deinem wege versucht jedoch hat sich nichts geändert.

    verstehe auch erhlich gesagt den unterschied zwischen:

    1.
    nLaenge=wsprintf(szNicknameBuffer, "02%s", pTail->szNickname);
    send(nSocket, szNicknameBuffer, nLaenge, 0);
    

    und

    2.
    wsprintf( szNicknameBuffer , "02%s\0", pTail->szNickname );          
    send( nSocket , szNicknameBuffer, strlen( szNicknameBuffer ) , 0 );
    

    nicht 😕

    naja , schlaft jut 😃



  • abgesehen davon das es die null nicht mitzählt ? ( bleibt ja noch immer die möglichkeit von strlen( string ) + 1 )



  • Wie intialisierst du den Socket welcher Port öffnest du einen Port über LocalHost oder hast du eine IP eingetragen ? hmmm... ansonsten.

    Du könntest eventuell jeden einzelnen Nutzer von der Gegenstelle quittieren lassen. Damit sollte es eigentlich auf alle Fälle funktionieren. !



  • hallo DaDaywalker ,

    port: 7777
    ip: INADDR_ANY

    initialisieren, ganz normal wsastartup() ausgeführt, danach struct sockaddr_in erst einmal mit memset() auf null gesetzt und die einzelnen datenfelder mit oben erwähnten daten beschrieben.

    was mit dem quittieren klingt gut , wie genau mach ich das ?

    mfg richi :p



  • quittieren einfach so, dass du nach dem senden eine antwort vom gegenüber erwartest:

    send(...);
    recv(...);
    // weiter...
    

    was evtl noch sein könnte, ist wie daniel gesagt hat, dass es zwischengespeichert wird. hast du bei deiner internetverbindung softwarekomprimierung eingestellt?

    letzte idee: frag per select ab, wann sich irgenwas auf dem (empfangs-)socket tut. sobald das ist, hol es ab und lösch so die warteschleife. (schau mal bei select beispielen, wie der netzwerkqueue nach dem empfangen gelöscht wird). so kriegst du immer nur das neueste, was reingekommen ist.

    würde aber primär mit dem quittieren arbeiten, da du so sehr effektive fehlerkontrolle machen kannst: du kannst z.b. so überprüfen, ob auch wirklich jeder name angekommen ist etc.



  • So wie Korbinian sagt solltest du die Quittierung durchführen.

    Im Klartext heißt das.

    Zum Beispiel könnte die Kommunikation zwischen den beiden Komponenten so aussehen. Könntest dir ein Beispiel am SMTP oder POP3 Server nehmen zwecks Kommunikation.

    1. Client -> Server 
       OK Client Version x.x.x.x,UserName=Ützelbrützel,Authentifizierung=tztztz
    2. Server -> Client
      2.1 Authentifizierung falsch
       ERR Authentification failed
      2.2 Authentifizierung richtig
       OK Begin send userprotocoll
    3. Client -> Server
       OK Ready
    4. Server -> Client
       Bruno
    5. Client -> Server
       OK Bruno
    6. Server -> Client
       Thorsten
    7. Client -> Server
       OK Thorsten
    

    etc. so könnte man das machen.
    Somit ist es möglich eine exakte Fehlerkontrolle zu realisieren.
    Solltest du Hilfe benötigen so schreib mir ne Mail und schick den Code mit
    [url=mailto:Dadaywalker@gmx.de">Dadaywalker@gmx.de[/url]

    [ Dieser Beitrag wurde am 08.01.2003 um 12:39 Uhr von DaDaywalker editiert. ]

    [ Dieser Beitrag wurde am 08.01.2003 um 12:40 Uhr von DaDaywalker editiert. ]



  • Wie sieht denn die Funktion zum Empfangen aus ?



  • hi,

    @nichi
    ich glaube, dein problem haben viele. zuerst musst du jeden string mit strlen +1 senden, da sonst die '\0' nicht mitgesendet wird. das ist geklaert. dein eigentliches koennte aber wo anders sein.

    du verschickst deine deine daten mit send. mehrere send aufrufe fuer aber auf der empfaenger seit nicht unbediingt zu mehreren recv aufrufen!

    beispiel:

    sender
    for( i = 0; i < 10; ++i)
    {
    sprintf( buff, "%d", i)
    send ( socket, buff, strlen( buff) +1 ,0)
    }

    empfaenger:
    len = 0;
    while( (len = recv( socket, buff, 4096, 0)) ! -1)
    {
    printf( "<%s> blen=%d slen=%d", buff, len, strlen( buff+1));
    }

    nach deinem ansatz muessten da auch 10 recv aufrufe kommen, dass muss aber nicht sein! ist slen != blen, dann wurde mehr als ein datensatz gleichzeitig gelesen. du musst dann mit einer weiteren schleife deinen puffer verarbeiten. jeder send aufruf wurde durch ein '\0' getrennt, also kannst du danach parsen

    geholfen?



  • kleiner nachtrag

    der ansatz mit dem ping pong (jedes packet bestaetigen) macht meiner meinung nach nur sinn bei udp verbindungen. bei tcp erhaelst du im regelfall eine fehlermeldung, wenn die daten nicht angekommen sind, also brauchst du sie im regelfall auch nicht einzeln bestaetigen.


Anmelden zum Antworten