Anzeige:
Ergebnis 1 bis 2 von 2

Thema: Select()

  1. #1
    Registrierter Benutzer
    Registriert seit
    08.05.2004
    Beiträge
    49

    Select()

    Hi,

    ich tuefftel schon seit ein paar Stunden an meinem Select aufruf herum. Ich habe das gefuehl das select() nicht mitbekommt wenn sich ein zweiter, dritter... client conected.

    Waere euch sehr verbunden wenn Ihr mal ueber den Sourcecode schaut ich sehe nix mehr. Bin der meinung das es so stimmt.

    Code:
    int main () {
    
      int intSock=0;
      int intBind=0;
      int intListen=0;
      int intSockNeu=0;
      int intResRead=0;
      int intResWrite=0;
      int intFdMax=0;
      int intSelect=0;
    
      /* Zaehlvariablen */
      int i=0, j=0;
    
      char chaBuf[MAXBUF];
    
      struct sockaddr_in strServer;
      struct sockaddr_in strClient;
    
      int intLaenServ;
      int intLaenClie;
    
      fd_set fdsread;
    
      intLaenServ = sizeof(strServer);
      intLaenClie = sizeof(strClient);
    
      /* Server Struct richtig einstellen */
      memset(&strServer, 0, sizeof(strServer));        /* clear structure */
      strServer.sin_family = AF_INET;
      strServer.sin_addr.s_addr = htonl(INADDR_ANY);
      strServer.sin_port = htons(PORT);
    
      intSock = socket(AF_INET, SOCK_STREAM, 0);
      if ((-1) == intSock) {
        perror("Anlegen des Socketes ging schief: ");
        exit(-1);
      }
    
      intBind = bind(intSock, (struct sockaddr*)  &strServer, intLaenServ);
      if ((-1) == intBind) {
        perror("Bind ging schief: ");
        exit(-1);
      }
    
      intListen = listen(intSock, 10);
      if ((-1) == intListen) {
        perror("Listen ging schief: ");
        exit(-1);
      }
    
      FD_ZERO(&fdsread);
      FD_SET(intSock, &fdsread);
    
      intFdMax = intSock;
    
      do {
        write(1,"DO\n",3);
    
        intSelect = select(intFdMax+1, &fdsread, NULL, NULL, NULL);
        if((-1) == intSelect) {
          perror("Select ging schief: ");
          exit(-1);
        }
        write(1, "NACH\n",5);
    
        for (i=0; i<=intFdMax; i++) {
          write(1,"FOR\n",4);
          if (FD_ISSET(i, &fdsread)) {
            /* Eine neue Verbindung hinzufuegen */
            if (i == intSock) {
              intSockNeu = accept(intSock, (struct sockaddr*) &strClient, &intLaenClie);
              if ((-1) == intSockNeu) {
                perror("Accept ging schief: ");
                exit(-1);
              }
              FD_SET(intSockNeu, &fdsread);
              if (intSockNeu > intFdMax) {
                intFdMax = intSockNeu;
              }
              write(1,"NEU\n",4);
            }
            else {
              /* empfange daten vom client */
              intResRead = recv(i, &chaBuf, MAXBUF, 0);
              if ((-1) == intResRead) {
                perror("Read ging schief: ");
                exit(-1);
              }
              write(1,chaBuf,intResRead);
    
            //  for (j=0; j<=intFdMax; j++) {
                /* Wenn der FD im FD_SET ist */
              //  if (FD_ISSET(j, &fdsread)) {
                  /* Nur wenn j != dem FD des connect Sockes ist und != des FD
                   * fuer das i steht */
              /*    if ((j != intSock) && (j != i)) {
                    intResWrite = write(1, chaBuf, intResRead);
                    if ((-1) == intResWrite) {
                      perror("Write ging schief: ");
                      exit(-1);
                    }
                  }
                }
              }*/
            }
          }
        }
      }while(TRUE);
    
      return 0;
    }
    Danke euch pfefferkeks

  2. #2
    Registrierter Benutzer
    Registriert seit
    02.07.2004
    Beiträge
    456
    Als allererstes solltest du mit zwei FD-Sets arbeiten. Eines, das quasi global in der Main existiert, und eines, das in der while-Schleife von Select am Anfang der Schleife immer als Kopie des main-globalen FD-Sets angelegt wird. Select manipuliert den Inhalt des FD-Sets, was sich übel auf den zweiten und die folgenden Schleifendurchläufe auswirkt. Daher solltest du bei jedem Schleifendurchlauf vor dem Select eine Kopie des eigentlichen FD-Sets anlegen und in Select mit dieser Kopie arbeiten, damit du Select immer das richtige FD-Set gibst. Bissl Pseudocode, syntaktisch nicht unbedingt korrekt:

    Code:
    int main()
    {
        fdset fglobal;
    
        int fd = socket(AF_INET, SOCK_STREAM,0)
        // Socket binden etc....
        .
        .
        .
    
        FDZERO(&fglobal);
        FDSET(fd, &fglobal);
    
        while(1) // select Schleife
        {
            struct timeval timeout;
            timeout.tv_sec = 1;
            timeout.tv_usec = 0;
            fdset flokal = fglobal;
            int retval = select(getdtablesize()+1, &flokal, NULL, NULL, &timeout);
            if(retval > 0) 
            {
                // Deskriptoren lesbar
            }
        }
        return 0;
    }
    So ähnlich.... ich hoffe, das hilft für's Verständnis.

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •