2014-03-30 44 views
1

我是套接字編程的新手,我已經介紹了select()系統調用。我的問題是,可以說我正在用C編寫一個服務器(我試圖這樣做),並且我想在我的實現中使用select()調用來練習。我試圖編寫一個從客戶端接收信息的服務器,所以我的方法是使用select(),然後是read()並輸出信息。在select()調用後知道哪些文件描述符已準備就緒C

根據我已閱讀的文檔select()返回數字文件描述符在輸入集準備I/O。我的問題是,如何知道哪個原始集合中的文件描述符是準備好用於I/O的文件描述符?我似乎無法在搜索過程中找到這些信息,或者我在過去查看了過去的示例。

比方說,我的代碼看起來像下面:

int main() { 
/* Create socket/server variables */ 
    int select_value; 
    int this_socket; 
    int maxfd; 
    struct sockadder_in address; 
    fd_set allset; 

    /* Bind the socket to a port */ 
    main_socket = socket(AF_INET, SOCK_STREAM, 0); 
    if (main_socket < 0) { 
     perror("socket()"); 
     exit(1); 
    } 

    Connect(main_socket, (struct sockaddr *)&address, sizeof(address)); 

    /* Add the socket to the list of fds to be monitored */ 
    FD_ZERO(&allset); 
    FD_SET(main_socket, &allset); 

    fd_set read_ready = allset; 
    fd_set write_ready = allset; 

    while (1) { 
     /* Listen for a connection */ 
     /* Accept a connection */ 
     select_value = Select(maxfd+1, &read_ready, &write_ready, NULL, NULL); 
     if (select_value == -1) { 
      perror("select()"); 
      exit(1); 
     } 
     else if(select_value > 0) { 
      /* How to access i/o ready file descriptors 
      now that we know there are some available? */ 
     } 
    } 
} 
+3

考慮使用[poll(2)](http://man7.org/linux/man-pages/man2/poll.2.html)而不是舊的'select'。谷歌的「C10K問題」 –

+0

我肯定會考慮它的未來實踐項目,感謝您的建議! – karysto

+0

RTFM,特別是'select'和'select_tut'的手冊頁。 –

回答

3

人們可以使用FD_ISSET宏是<sys/select.h>部分做到這一點。

當您的select解鎖並且文件描述符已準備好時,您可以使用FD_ISSET宏以簡單循環測試所有文件描述符。這可以轉換爲下面的示例:

for (i = 0; i < FD_SETSIZE; ++i) { 
    if (FD_ISSET (i, &read_fd_set)) { 
     if (i == bound_socket) { 
      // A new client is waiting to be accepted 
      new = accept(sock, (struct sockaddr *) &clientname, &size); 
      // ... 
      FD_SET (new, &active_fd_set); 
     } 
     else { 
      // There is something to be read on the file descriptor. 
      data = read_from_client_on(i); 
     } 
    } 
} 

當然,這只是品嚐這顯然是缺乏任何錯誤處理,你應該在你的應用程序處理。

+0

嘿,非常感謝,這是一個簡單的解釋。我忘了select()是作爲一個位掩碼來實現的,所以我直到看到你的解釋和循環時才理解使用FD_SET。 – karysto