Select 功能會判斷一個或多個套接字的狀態,必要時會等待執行同步 I/O。
語法
int WSAAPI select(
[in] int nfds,
[in, out] fd_set *readfds,
[in, out] fd_set *writefds,
[in, out] fd_set *exceptfds,
[in] const timeval *timeout
);
參數
[in] nfds
忽略。 nfds 參數僅為與 Berkeley 套接字相容而加入。
[in, out] readfds
一個可選的指標指向一組需要檢查可讀性的插槽。
[in, out] writefds
一個可選的指標指向一組需要檢查可寫性的套接字。
[in, out] exceptfds
一個可選的指標,指向一組需要檢查錯誤的套接字。
[in] timeout
選擇等待的最長時間,以 TIMEVAL 結構形式提供。 將 逾時 參數設為 空 ,以便進行阻塞操作。
返回值
select 函式回傳已準備好並包含在 fd_set 結構中的套接字句柄總數,時間限制過時為零,錯誤則為 SOCKET_ERROR。 如果回傳值為 SOCKET_ERROR,WSAGetLastError 可用來檢索特定的錯誤碼。
| 錯誤碼 | Meaning |
|---|---|
| 使用此函式之前,必須先進行成功的 WSAStartup 呼叫。 | |
| Windows Sockets 實作無法為其內部操作分配所需資源,或是 readfds、 writefds、 exceptfds 或 timeval 參數不屬於使用者位址空間。 | |
| 網路子系統發生故障。 | |
| 若逾時值無效,或三個描述符參數皆為空指標或指向無套接字的空 fd_set 結構有效指標,則回傳 WSAEINVAL。 | |
| 一則阻塞 Windows Socket 1.1 呼叫透過 WSACancelBlockingCall 被取消。 | |
| 封鎖 Windows Sockets 1.1 呼叫正在進行中,或服務提供者仍在處理回呼函式。 | |
| 其中一個描述符集合包含一個不是套接字的項目。 |
備註
Select 功能用於判斷一個或多個套接字的狀態。 呼叫者可以針對每個套接字請求讀取、寫入或錯誤狀態的資訊。 請求特定狀態的套接字集合由 fd_set 結構標示。 fd_set結構中包含的套接字必須與單一服務提供者相關聯。 為了此限制,若描述協定的 WSAPROTOCOL_INFO 結構具有相同的 providerId 值,則該套接字視為來自同一服務提供者。 回傳時,結構會更新以反映符合指定條件的這些套接字子集。 Select 函式會回傳符合條件的套接字數量。 提供一組巨集用於操作 fd_set 結構。 這些巨集與柏克萊軟體中使用的巨集相容,但底層表示方式完全不同。
參數 readfds 用來識別需要檢查可讀性的插槽。 如果套接字目前處於 監聽 狀態,且已收到入站連線請求,且保證 接受 會完成且不會阻塞,該套接字會被標記為可讀。 對於其他套接字,可讀性意指排隊資料可供讀取,確保呼叫 recv、 WSARecv、 WSARecvFrom 或 recvfrom 不會被阻塞。
對於連線導向套接字,可讀性也可能表示已收到對端端關閉套接字的請求。 如果虛擬電路順利閉合,且所有資料都已接收, 則 recv 會立即返回,且讀取位元組為零。 若虛擬電路被重置, 則 recv 會立即完成,並出現如 WSAECONNRESET 的錯誤代碼。 若套接字選項SO_OOBINLINE已啟用,則會檢查 OOB 資料的存在(參見 setsockopt)。
參數 writefds 用來識別需要檢查可寫性的套接字。 若套接字正在處理 連接 呼叫(非阻塞),若連線建立成功完成,該套接字是可寫入的。 若套接字未處理 連接 呼叫,可寫性表示 send、 sendto 或 WSASendto 必定成功。 然而,如果 len 參數超過系統緩衝區的輸出空間,它們可以在阻塞套接字上進行阻塞。 並未明確說明這些保證可以假定有效多久,特別是在多執行緒環境中。
參數 exceptfds 用來識別需要檢查是否有 OOB 資料或任何特殊錯誤狀況的套接字。
總結來說,當 select 回傳時,當 select 回傳時,套接字會在特定集合中被識別,條件是:
ReadFDS:
WriteFDS:- 若處理 連線 通話(非阻塞),則連線成功。
- 資料可以傳送。
- 若處理 連線 通話(非阻塞),連線嘗試失敗。
- OOB 資料可供讀取(只有在 SO_OOBINLINE 被停用時)。
- FD_ZERO(*set) - 初始化 set 為空集合。 使用前應該先清除一組。
- FD_CLR(s, *set) - 從集合中移除插槽 s。
- FD_ISSET(s, *set) - 檢查 s 是否屬於 set,若是則回傳 TRUE。
- FD_SET(s, *set) - 新增 socket s 到 set。
參數逾時控制選擇完成所需的時間。 若 逾時 為 空 指標, select 將無限期封鎖,直到至少一個描述符符合指定條件。 否則 ,逾時 會指向一個 TIMEVAL 結構,該結構指定 select 在返回前應等待的最長時間。 當 選擇 返回時, TIMEVAL 結構的內容不會被更改。 若 TIMEVAL 初始化為 {0, 0}, select 會立即返回;此用來輪詢所選套接字的狀態。 如果 select 立即返回,則該 select 呼叫被視為非阻塞呼叫,且標準的非阻塞呼叫假設適用。 例如,阻擋鉤子不會被呼叫,Windows Sockets 也不會被 drop。
Windows 8.1 和 Windows Server 2012 R2:Windows 8.1、Windows Server 2012 R2 和更新版本上的 Windows 市集應用程式支援此功能。
需求
| Requirement | 價值觀 |
|---|---|
| 最低支援的用戶端 | Windows 8.1、Windows Vista [傳統型應用程式 |UWP 應用程式] |
| 支援的最低伺服器 | Windows Server 2003 [傳統型應用程式 |UWP 應用程式] |
| 目標平臺 | 窗戶 |
| Header | winsock2.h |
| Library | Ws2_32.lib |
| DLL | Ws2_32.dll |