2012-10-25 64 views
0

我連接到某個客戶端,然後我們正在進行通信。另一個客戶端連接到我的服務器,它會立即輸出,有一個新的連接..例如接受,而聆聽其他客戶端?..我怎麼能這樣做?..select()在讀取和接收客戶端數據時接受連接

我已經工作,但它只有一個一次一件事。當我已經與我的客戶進行通信時,我無法接受到其他客戶的傳入連接或數據。當我通信的客戶端斷開連接時,我只能接受來自其他客戶端的新連接或數據。我該怎麼做,以便它可以同時處理接受和聽取客戶端。我不想使用線程。

這是我的代碼的一部分。

do 
{ 
    fduse = fdin; 
    printf("Waiting for Connection\n"); 
    err = select(sMax + 1, &fduse, NULL, NULL, NULL); 
    if (err < 0) 
    { 
     perror(" select() failed"); 
     break; 
    } 
    DescRead = err; 
    for (SockStorage = 0; SockStorage <= sMax && DescRead > 0; ++SockStorage) 
    { 
     if (FD_ISSET(SockStorage, &fduse)) 
     { 
     DescRead -= 1; 
     if (SockStorage == socketFd) 
     { 
      printf(" Listening socket is readable\n"); 
      do 
      { 
       NewSFD = 
        accept(socketFd, (struct sockaddr *)&cli_addr, &clilen); 
       if (NewSFD < 0) 
       { 
        if (errno != EWOULDBLOCK) 
        { 
        perror(" accept() failed"); 
        DCSERVER = TRUE; 
        } 
        break; 
       } 
       if (ClientCount < MAX_CLIENTS) 
       { 
        for (loop = 0; loop < MAX_CLIENTS; loop++) 
        { 
        if (Clients[loop].connected_sock < 0) 
        { 
         Clients[loop].connected_sock = NewSFD; 
         break; 
        } 
        } 
        ClientCount++; 
       } 
       else 
       { 
        printf("Maximum Client Reached.\n"); 
        char *sendtoclient = "Server full. "; 
        send(NewSFD, sendtoclient, strlen(sendtoclient), 0); 
        close(NewSFD); 
        break; 
       } 
       ip = ntohl(cli_addr.sin_addr.s_addr); 
       printf(" Connection from %d.%d.%d.%d\n", 
        (int)(ip >> 24) & 0xff, 
        (int)(ip >> 16) & 0xff, 
        (int)(ip >> 8) & 0xff, (int)(ip >> 0) & 0xff); 
       dlogs(ip); 

       FD_SET(NewSFD, &fdin); 
       if (NewSFD > sMax) 
        sMax = NewSFD; 
      } 
      while (NewSFD != -1); 
     } 
     else 
     { 
      int d; 
      for (d = 0; d < MAX_CLIENTS; d++) 
      { 
       printf("Descriptor ID: %d\n", Clients[d].connected_sock); 
      } 

      pfds[0].fd = fd; 
      pfds[0].events = POLLIN; 
      pfds[1].fd = SockStorage; 
      pfds[1].events = POLLIN; 
      state = FALSE; 
      do 
      { 
       rc = poll(pfds, 2, -1); 
       if (pfds[0].revents & POLLIN) 
       { 
        while ((nbytes = read(fd, buf, sizeof (buf) - 1)) > 0) 
        { 
        buf[nbytes] = '\0'; 
        printf("%s\n", buf); 
        } 
        pfds[0].events = 0; 
        pfds[1].events = POLLIN | POLLOUT; 
       } 
       if (pfds[1].revents & POLLIN) 
       { 
        err = recv(SockStorage, strbuf, sizeof (strbuf), 0); 
        if (err < 0) 
        { 
        if (errno != EWOULDBLOCK) 
        { 
         perror(" recv() failed"); 
         state = TRUE; 
        } 
        break; 
        } 
        if (err == 0) 
        { 
        printf(" Connection closed\n"); 
        state = TRUE; 
        break; 
        } 
        dSize = err; 
        printf(" %d bytes received\n", dSize); 
       } 

       if (pfds[1].revents & POLLOUT) 
       { 
        int s; 
        for (s = 0; s < MAX_CLIENTS; s++) 
        { 
        if (Clients[s].connected_sock > 0) 
        { 
         err = 
          send(Clients[s].connected_sock, buf, 
          strlen(buf), 0); 
         if (err < 0) 
         { 
          perror(" send() failed"); 
          track = s; 
          state = TRUE; 
          break; 
         } 
        } 
        } 
        pfds[0].events = POLLIN; 
        pfds[1].events = POLLIN; 
       } 

      } 
      while (TRUE); 
      fopen("/sockF.txt", "w"); 
      if (state) 
      { 
       ClientCount--; 
       close(SockStorage); 
       FD_CLR(SockStorage, &fdin); 
       if (SockStorage == sMax) 
       { 
        while (FD_ISSET(sMax, &fdin) == FALSE) 
        sMax -= 1; 
       } 
      } 
     } 
     } 
    } 
} while (DCSERVER == FALSE); 
cleanUP(SockStorage, sMax); 
} 

我一直工作在這兩天,我仍然無法得到它。感謝..

+1

我建議你不要有這麼多多餘的空白在你的代碼示例張貼問題時。它使用戶難以查看您的問題。我會編輯這個問題,但似乎還有另一個掛起的編輯。 – ecbrodie

+0

......編輯確實是我的建議。你走了! – ecbrodie

+0

感謝您的編輯:) – demic0de

回答

0

好了,給你工作多連接守護進程的一個例子,看看this example

如果您需要進一步的解釋去用它,拍攝。

請注意,該示例中的代碼已被刪除,如daemon_init()等,所以只是盲目複製粘貼並嘗試編譯它不起作用。按照請求添加setnonblocking()

void setnonblocking(sock) 
    int sock; 
{ 
    int opts; 

    opts = fcntl(sock, F_GETFL); 

    if (opts < 0) 
    { 
     syslog(LOG_ERR, "fcntl(F_GETFL) failed"); 
     exit(EXIT_FAILURE); 
    } 

    opts = (opts | O_NONBLOCK); 

    if (fcntl(sock, F_SETFL, opts) < 0) 
    { 
     syslog(LOG_ERR, "fcntl(F_SETFL) failed"); 
     exit(EXIT_FAILURE); 
    } 

    return; 
} 

而且daemon_init()

int daemon_init(void) 
{ 
    pid_t pid; 
    int i; 


    if ((pid = fork()) < 0) 
    { 
     return -1; 
    } 
    else if (pid != 0) 
    { 
     exit(0); 
    } 

    for (i=getdtablesize();i>=0;--i) close(i); 
    i = open("/dev/null", O_RDWR); /* open stdin */ 
    dup(i); /* stdout */ 
    dup(i); /* stderr */ 

    setsid(); 
    return 0; 
} 
+1

感謝您的代碼..什麼是setnonblocking內?它是否是ioctl? – demic0de

+1

粘貼到答案中。 – favoretti

+1

謝謝... ioctl和fcntl有什麼區別?因爲我一直在使用fcntl和一個文件和ioctl套接字。 – demic0de

相關問題