2011-05-21 26 views
2

我有一個fd_set「write_set」,它包含我想用於發送(...)調用的套接字。當我調用select(maxsockfd + 1,NULL,& write_set,NULL,& tv)時,它總是返回0(超時),儘管我還沒有在write_set套接字上發送任何東西,並且應該可以發送數據。select()行爲是否具有可寫性?

這是爲什麼?在可以通過write_set中的套接字發送數據時,不應該立即選擇返回?

謝謝!

編輯:我的代碼..

// _read_set and _write_set are the master sets 
fd_set read_set = _read_set; 
fd_set write_set = _write_set; 

// added this for testing, the socket is a member of RemoteChannelConnector. 
std::list<RemoteChannelConnector*>::iterator iter; 
for (iter = _acceptingConnectorList->begin(); iter != _acceptingConnectorList->end(); iter++) { 

    if(FD_ISSET((*iter)->getSocket(), &write_set)) { 

     char* buf = "a"; 
     int ret; 
     if ((ret = send((*iter)->getSocket(), buf, 1, NULL)) == -1) { 
      std::cout << "error." << std::endl; 
     } else { 
      std::cout << "success." << std::endl; 
     } 

    } 

} 

struct timeval tv; 
tv.tv_sec = 10; 
tv.tv_usec = 0; 

int status; 

if ((status = select(_maxsockfd, &read_set, &write_set, NULL, &tv)) == -1) { 

    // Terminate process on error. 
    exit(1); 

} else if (status == 0) { 

    // Terminate process on timeout. 
    exit(1); 

} else { 
// call send/receive 
} 

當我進行測試的代碼運行它,如果我的插座實際上是在write_set,如果有可能在插座發送數據時,我得到一個「成功「......

+0

你確定_maxsockfd正確嗎?它必須比任何read_set或write_set中的文件描述符大1。在上面的實際代碼中,你沒有_maxsockfd + 1,你在問題中做了什麼。 – nos 2011-05-21 12:19:58

+0

-1代表C++代碼標記C.另外,用'_'前綴符號名稱幾乎總是錯誤的。 – 2011-05-21 12:24:51

+0

@nos噢,是的,謝謝你。 – simon 2011-05-21 12:31:22

回答

0

我不認爲你被允許複製構建fd_set對象。唯一可以保證的方法是在每次調用select之前使用FD_SET完全重建該組。此外,您在致電select之前,要寫入要選擇的套接字列表。這沒有意義。

您可以用poll代替嗎?這是一個非常友好的API。

+1

關於複製fd_sets:http://stackoverflow.com/questions/2421672/are-there-any-platforms-where-using-structure-copy-on-an-fd-set-for-select-或 – 2011-05-21 13:18:20

+0

隨着「寫作到要選擇的套接字列表「是否指的是send()調用?如果是的話,這純粹是爲了測試,而不是在實際的代碼中。我只是想測試套接字是否真的在套中,如果我可以發送一些東西在他們身上。 @約翰謝謝,我會用FD_COPY。 – simon 2011-05-21 13:57:56

0

你的代碼很混亂。首先,你似乎沒有設置fd_set中的任何位。其次,在你打電話給select之前,你測試一下這些位。

這裏是如何的水流方式一般工程...

  • 使用FD_ZERO零出你的設置。
  • 請仔細閱讀,對於每個文件描述符,您都對可寫狀態感興趣,請使用FD_SET進行設置。
  • 請致電select,將fd_set的地址傳遞給您寫入集的FD_SET函數,並觀察返回值。
  • 如果返回值大於0,則通過寫入集並使用FD_ISSET來確定哪些仍然設置。那些是可寫的。

您的代碼似乎完全不遵循此模式。此外,設置主設備的重要任務未被顯示。

相關問題