nur Timer oder nonblocking sockets mit timer - entscheidungshilfe...



  • Hi, ich möchte ein Socket für etwa 30 Sek. offen halten, wenn Daten ankommen, soll es evt. aber auch länger offen bleiben, und wenn nichts nach 30 sek. ankam soll es halt auch schließen.

    ich bin noch ziemlicher C newbie... habe mich vorher weder mit nonblocking socket noch mit timern auseinander gesetzt.

    ich dachte mir das entweder so (pseudocode...)

    while (timer < 30 sekunden){
    recvfrom(socket, buf, blabla);
    }

    oder halt so:

    recvfrom(nonblockingSocket);
    start timer
    if (timer == 30 sekunden) {
    closesocket(nonblockingSocket);

    ich denke der unterschied ist zu sehen, gell.
    welche richtung sollte ich einschlagen ?



  • Die frage ist halt auch, ob die erste version überhaupt funktionieren kann, oder ob so ein Blocking socket auch den Timer blockiert.



  • eigentlich kann ich mir die Antwort schon selber geben... die erste version funktioniert wahrscheinlich nur mit Threads...



  • Du könntest auch über select den Socket abfragen, z.B. mit einem Timer 30 mal im Sekundenintervall. Wenn du die Timeout-Var. mit "0" (nicht "NULL"!) initialisierst, arbeitet select nicht-blockierend.

    Rob'



  • ähm, besteht da nicht die gefahr, das einem daten entgehen ? (gillt genauso für non blocking sockets...)



  • ok, ich werde es mit select machen. Aber da muß man ja einen Timer übergeben - wie mache ich das im Borland c compiler ?

    kann ich einfach so einen zeiger auf die

    struct timeval * off_time;
    

    machen, oder muß ich eine Kopie dieser Struktur erstellen ? Vor allem will ich ja auch den Timer unter umständen wieder hochsetzen, wenn ein "let the port please open" 😃 command über Udp reinkommt.

    Was ich auch nicht verstehe sind die Makros FD_ - denen wird ja ein Socket (oder ein Array) übergeben. Was macht das makro FD_ZERO nun mit dem dem Socket ? Was wird verändert ? Ich weiß das in der WIN-API Hilfe "initializes the set to the NULL set" steht, aber das sagt mir ehrlich gesagt, garnichts.

    muß das select dann noch in eine While schleife um zu funktionieren, oder zählt so ein Timer von alleine, naja, will halt wissen wie ich so einen timer starte, und anhalte und so... ?



  • [ Dieser Beitrag wurde am 05.12.2002 um 05:30 Uhr von Backtickz editiert. ]



  • hier mein funktionierender code, aber das socket kehrt nicht nach 30 sek. aus dem receive zurück, sondernd es geht sofort weiter...

    int set_nobloc(void){
    #define command FIONBIO
    u_long FAR arg = 1;
    // socket in non-blocking mode setzen:
    rc = ioctlsocket(r,command,&arg);
    if (rc != 0){printf("error in set_nobloc: %d\n", WSAGetLastError());
    return 1;}
    else{printf("Socket in non-block Mode geschaltet\n");}
    return 0;
    }
    
    int rcv_short(void){
    int remoteAddrLen=sizeof(SOCKADDR_IN);
    int max = 0;
    fd_set rcv_sock_list;      // readable liste für socket deskriptoren alias erstellen
    struct timeval  timeout; // timer struktur erzeugen
    timeout.tv_sec = 30;       // timer sek. auf 30 setzen
    timeout.tv_usec = 0;         // mil. Sek. auf Null !
    
    rc=bind(r,(SOCKADDR*)&localAddr,sizeof(SOCKADDR_IN));
    
    if (s > r){max = s;}
    else{max = r;}
    FD_SET(r, &rcv_sock_list); //socket r (receiver) zur readable liste zufügen
    select(max + 1, &rcv_sock_list, NULL, NULL, &timeout);
    while (timeout.tv_sec != 60){
       rc=recvfrom(r,buf,strlen(buf),0,(SOCKADDR*)&remoteAddr,&remoteAddrLen);
    }
       if (rc == 0) {
       printf ("es wurden keine daten empfangen");
       }else{
             printf("es wurden %d bytes empfangen", rc);
             }
       printf("socket war für 30 sek. geöffnet");
    
    return 0;
    }
    

    wenn ich ein sleep oder wait (weiß nicht wie die anhalte funktion in c heißt...) in die while schleife einbaue, würden in der sleep zeit dann trotzdem noch daten in den IP Stack gepusht (also ich meine die die ich haben will), oder gehen die daten, die in der wartesek. ankommen, verloren ?

    [ Dieser Beitrag wurde am 05.12.2002 um 13:05 Uhr von Backtickz editiert. ]



  • ähm, giebt es eine möglichkeit den timer jede sek. um einz zu erhöhen oder zu dekrementieren ?



  • ich wollt nochmal eben dafür sorgen das das Thema nicht in vergessenheit gerät... Ich denke ich muß das wohl mit Threads oder einer DLL oder mit sowas wie Fork() bei Perl... machen ?


Anmelden zum Antworten