2016-03-03 54 views
-1

我知道選擇在返回時修改輸入集。但是如何? 輸入集中的fd如何不在輸入集中? fd_isset(fd)將返回true,在我看來,只要fd在開始處的輸入集中。那麼select()如何修改其輸入集呢?select()如何修改其輸入集?

這是FD_SET結構:

typedef struct fd_set { 
    u_int fd_count; 
    SOCKET fd_array[FD_SETSIZE]; 
} fd_set; 

那麼哪些字段將被選擇進行更新()?我們仍然想跟蹤所有的fd,所以我不明白select()更改fd_count或fd_array是否合理?那麼,select()會改變什麼?

從手冊頁:

「退出時,集合到位,以指示哪些文件描述符實際上改變狀態的影響。」

但是,有關組中的WHAT方面的細節已經明顯缺失。

編輯: 對此問題的回答: 那麼下面是正確的使用方法嗎?

while (not error and not socket closes){ 
    FD_ZERO(&readSet); 
    FD_ZERO(&writeSet); 
    FD_SET(fd, &readSet); 
    FD_SET(socket_num, &readSet); 
    FD_SET(fd, &writeSet); 
    FD_SET(socket_num, &writeSet); 
    select(nfds, &readSet, writeSet, NULL, NULL); 
    if(FD_ISSET(fd, &readSet)){ 
     read(fd, buf, sizeof(buf)); 
     write(socket_num, buf, sizeof(buf)); 
     /*memset(buf, 0, sizeof(buf));*/ 
    } 
    if(FD_ISSET(socket_num, &readSet)){ 
     read(socket_num, buf, sizeof(buf)); 
     write(fd, buf, sizeof(buf)); 
    } 
} 
+0

請推薦相關標籤。唯一我能想到的是c ... –

+0

「哪些文件描述符實際上改變了狀態」對我來說非常清楚。爲什麼要修改計數? – Olaf

+0

除了缺少一個'&'之外,你插入更新的代碼看起來好像它可能是使用'select()'的有效方法。它實際上是否有效取決於該代碼出現的上下文的許多細節。 –

回答

2

在輸入時,fd_set告訴select()它應該檢查哪些FD。 select製作此列表的副本以供其內部使用。當它返回時,它會修改輸入結構以包含返回的信息。它可以修改fd_countfd_array

這就是爲什麼使用select()迴路循環之前通常保存fd_set的副本,並複製此回該公司在select()通話每次使用通過循環變量,例如

FD_SET(sockfd, &fd_set_init); 
while(true) { 
    FD_COPY(&fd_set_init, &fd_set); 
    n = select(nfds, &fd_set, NULL, NULL, NULL); 
    if (n > 0) { 
     // Use fd_set here 
    } 
} 
+0

謝謝,我編輯了我的問題。 –

+0

在'select'調用中,你在'writeset'之前缺少'&'。但是否則它是正確的。 – Barmar

+0

謝謝。我會在這裏鏈接我的完整代碼。 http://stackoverflow.com/questions/35762852/in-c-proxy-http-requests-to-another-server –

2

select()功能需要指針的各種文件描述符套它的參數之一。它可以通過這些指針修改FD集,方式與任何函數都可以修改傳遞給它的任何指針的引用相同。鑑於您提供的fd_set定義,它可能會通過寫入fd_array成員[update:]的相應元素以及可能還有fd_count成員來完成。

但是,請注意,您提供的結構定義是fd_set結構是錯誤的。假設你從與你相關的頭文件中提取它,所以它是fd_set結構,但結構定義沒有記錄,所以它可能在其他系統上以不同方式實現。這是爲什麼FD_*()函數用於操作這些結構的內容的一個原因。

與您的問題特別相關,您可以使用FD_ISSET()select()返回後測試文件描述符集的內容。

+0

非常感謝。這非常有幫助。 –

+0

具體來說,它看起來像Windows中的'fd_set'結構。 – o11c