winsock + select = probleme



  • hi,
    ich hab nen kleines server-client programm geschrieben!
    funktioniert auch wunderbar ( auch das annehmen von mehreren connections )

    nur wenn es darum geht mit den beiden zu kommunizieren scheitere ich..

    vorweg: ich hab mir das PSDK angeguckt , war auf den verschiedensten seiten (c-worker,etc.) aber ahb keine lösung gefunden..

    hier mal nen bisschen code mit erklärungen:
    [cpp]
    server
    fd_set socks;

    FD_ZERO(&socks); // leeren

    FD_SET(conSocket[0],&socks);
    FD_SET(conSocket[1],&socks);

    char buf[100];
    long bc = 0;

    while(1)
    {
    select(0,&socks,NULL,NULL,NULL);

    bc=recv(/*hier*/,buf,100,0); //wie stelle ich das jetzt an das ich von //dem client lese der grade etwas sendet

    if (bc > 0)
    {
    buf[bc] = '\0';
    cout << buf << endl;

    if (buf[0] == 'X')
    break;
    }
    };[/cpp]

    der code ist jetzt leider schon ziemlich kaputt
    ich hoffe trotzdem das mir jemand dazu nen paar tips geben kann



  • ich vermute mal, du hast nonblocking sockets (was bei select oft gemacht wird). falls ja, dann frag einfach nach dem select alle sockets ab. auf dem socket, auf dem was reingekommen ist, ist recv(sock, ...) größer 0. entsprechend kannst de dann alle einkommenden sachen verarbeiten.



  • danke erstmal so hab ich das jetz:

    fd_set socks;
    
    FD_ZERO(&socks);
    
    FD_SET(connectedSocket[0],&socks);
    FD_SET(connectedSocket[1],&socks);
    
    timeval to;
    
    to.tv_sec = 1;
    to.tv_usec = 0;
    
    char buf__[100];
    long bc = 0;
    int g = 0;
    
    while(1)
    {
        select(0,&socks,NULL,NULL,&to);
    
        for (g = 0;g<2;g++)
        {
        bc = recv(connectedSocket[g],buf__,99,0);
        if (bc > 0)
            {
        buf__[bc] = '\0';
        cout << buf__ << endl;
            if (buf__[0] == 'X')
                break;
            }
        };      
    };
    

    nur kommt nur die hälfte an:

    wenn ich bei einem client bleibe und dann mehrere sachen schreibe (sende) geht ja alles toll nur wenn ich abwechselnt oder so sachen schicke dann kommt nur die hälfte an bzw. mit einer evig langen verzögerung



  • PS: ich vermute mal, du hast nonblocking sockets

    öhm.. ich dachte durch das select() habe ich non blocking sockets...
    wenn dem nicht so ist wie bekomm ich denn dann nonblocking sockets?!?



  • hm, keine ahnung 😃 unter linux gehts mit fcntl. das 0 bei select kommt mir bisschne spanisch vor. da muss der gröste socketdeskriptor+1 hin.
    zu deinen zeitverzögerungen. ich würde mal bei select ein timeout einbauen:

    struct timeval tv; // ich weis nicht genau was du in Win32 dafür includieren musst
    tv.tv_sec = 60; // 1 Minute
    tv.tv_usec = 0;
    ...
    int max = GibGroestenSocket(); // bau nen kleinen Algo, um an den größten deskriptor zu kommen.
    // wenn du nur 2 sockets hast isses leicht:
    if (sock1 > sock2)
        max = sock1;
    else
        max = sock2;
    int ret = select (max + 1, &socks, NULL, NULL, &tv);
    switch (ret)
    {
        case -1: // fehler
        case 0:  // Timeout
        default: // Daten verfügbar :)
    }
    


  • hi, danke!

    -> hab jetzt leider keine zeit das auszuprobieren...

    aber die 0 bei select hab ich desshalb:

    PSDK:*
    int select(
    int nfds,
    [...]
    Parameters
    nfds
    [in] Ignored. The nfds parameter is included only for compatibility with Berkeley sockets.
    *

    und des time. hab ich dringehabt war aber kein unterschied... ob mit time. oder ohne..

    deskriptor

    was heißt das überhaupt?! bzw. wie soll ich den größten rausfinden wieso haben die ne verschiedene größe?!?! 😕

    so das währs dann auch erst mal!
    -> ich glaub ich bin zu dumm dazu...



  • die heist so: socketdeskriptor (variable die einen socket beschreibt). haben unterschiedliche werte (integer). fangen irgenwo klein an und werden dann halt immer größer 🙂 eine socketvariable ordnet einen socket eindeutig für das bs zu (glaub ich)



  • achso *das alngsam versteh*

    jetz hab ich mich mal an den code gemacht..

    und:

    //schleife hier starten?!?
    int ret = select (max + 1, &socks, NULL, NULL, &tv);
    switch (ret)
    {
        case -1: 
        case 0:  
        default: und von welchem socket kann ich jetzt lesen?!?!?
    }
    //schleifen ende?!
    


  • das mit den schleifen is so ungefähr richtig. lesen musst du von jedem socket, und bei denen, deren rückgabewert größer als 0 ist hast du was empfangen und kannst es dann auswerten 🙂


Anmelden zum Antworten