共用方式為


Select 函數(Winsock2.h)

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
WSANOTINITIALIZED
使用此函式之前,必須先進行成功的 WSAStartup 呼叫。
WSAEFAULT
Windows Sockets 實作無法為其內部操作分配所需資源,或是 readfdswritefdsexceptfdstimeval 參數不屬於使用者位址空間。
WSAENETDOWN
網路子系統發生故障。
WSAEINVAL
若逾值無效,或三個描述符參數皆為指標或指向無套接字的空 fd_set 結構有效指標,則回傳 WSAEINVAL
WSAEINTR
一則阻塞 Windows Socket 1.1 呼叫透過 WSACancelBlockingCall 被取消。
WSAEINPROGRESS
封鎖 Windows Sockets 1.1 呼叫正在進行中,或服務提供者仍在處理回呼函式。
WSAENOTSOCK
其中一個描述符集合包含一個不是套接字的項目。

備註

Select 功能用於判斷一個或多個套接字的狀態。 呼叫者可以針對每個套接字請求讀取、寫入或錯誤狀態的資訊。 請求特定狀態的套接字集合由 fd_set 結構標示。 fd_set結構中包含的套接字必須與單一服務提供者相關聯。 為了此限制,若描述協定的 WSAPROTOCOL_INFO 結構具有相同的 providerId 值,則該套接字視為來自同一服務提供者。 回傳時,結構會更新以反映符合指定條件的這些套接字子集。 Select 函式會回傳符合條件的套接字數量。 提供一組巨集用於操作 fd_set 結構。 這些巨集與柏克萊軟體中使用的巨集相容,但底層表示方式完全不同。

參數 readfds 用來識別需要檢查可讀性的插槽。 如果套接字目前處於 監聽 狀態,且已收到入站連線請求,且保證 接受 會完成且不會阻塞,該套接字會被標記為可讀。 對於其他套接字,可讀性意指排隊資料可供讀取,確保呼叫 recvWSARecvWSARecvFromrecvfrom 不會被阻塞。

對於連線導向套接字,可讀性也可能表示已收到對端端關閉套接字的請求。 如果虛擬電路順利閉合,且所有資料都已接收, 則 recv 會立即返回,且讀取位元組為零。 若虛擬電路被重置, 則 recv 會立即完成,並出現如 WSAECONNRESET 的錯誤代碼。 若套接字選項SO_OOBINLINE已啟用,則會檢查 OOB 資料的存在(參見 setsockopt)。

參數 writefds 用來識別需要檢查可寫性的套接字。 若套接字正在處理 連接 呼叫(非阻塞),若連線建立成功完成,該套接字是可寫入的。 若套接字未處理 連接 呼叫,可寫性表示 sendsendtoWSASendto 必定成功。 然而,如果 len 參數超過系統緩衝區的輸出空間,它們可以在阻塞套接字上進行阻塞。 並未明確說明這些保證可以假定有效多久,特別是在多執行緒環境中。

參數 exceptfds 用來識別需要檢查是否有 OOB 資料或任何特殊錯誤狀況的套接字。

只有當選項SO_OOBINLINE為 FALSE,帶外資料才會以這種方式報告。 若一個套接字正在處理 連接 呼叫(非阻塞),連接嘗試失敗會在 exceptfds 中顯示(應用程式必須呼叫 getsockopt SO_ERROR 以判斷錯誤值以描述失敗原因)。 本文件未規定將包含哪些其他錯誤。
 
readfdswritefdsexceptfds 中任意兩個參數都可以被指定為 null。 至少有一個必須是非的,且任何非 描述符集合必須包含至少一個套接字的句柄。

總結來說,當 select 回傳時,當 select 回傳時,套接字會在特定集合中被識別,條件是:

ReadFDS

  • 如果已經呼叫聆聽且連線待處理,接受會成功。
  • 資料可供讀取(若啟用SO_OOBINLINE則包含物件外資料)。
  • 連線已被關閉/重置/終止。
WriteFDS
  • 若處理 連線 通話(非阻塞),則連線成功。
  • 資料可以傳送。
除FDS
  • 若處理 連線 通話(非阻塞),連線嘗試失敗。
  • OOB 資料可供讀取(只有在 SO_OOBINLINE 被停用時)。
Winsock2.h 標頭檔案中定義了四個巨集,用於操作與檢查描述符集合。 變數 FD_SETSIZE 決定集合中描述子的最大數量。 (FD_SETSIZE 的預設值為 64,可在包含 Winsock2.h 前將 FD_SETSIZE 定義為其他值來調整。)在內部, fd_set 結構中的套接字手塊不像 Berkeley Unix 那樣以位元旗標表示。 他們的資料呈現是不透明的。 使用這些巨集可維持軟體在不同套接字環境間的可攜性。 操作和檢查 fd_set內容 的巨集有:
  • 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。

Select 功能不會影響 WSAAsyncSelectWSAEventSelect 註冊的套接字事件的持久性。
 
當發出阻擋性的 Winsock 呼叫(如 select 且將 逾時參數 設為 NULL)時,Winsock 可能需要等待網路事件後才能完成通話。 Winsock 會在此情況下執行可警示等候,這可能會由相同執行程上排程的非同步程式呼叫 (APC) 中斷。 在中斷相同執行程上進行的封鎖 Winsock 呼叫的 APC 內發出另一個封鎖 Winsock 呼叫,會導致未定義的行為,而且 Winsock 用戶端絕不能嘗試。
 
Windows 電話 8: Windows Phone 8 和更新版本上的 Windows Phone 市集應用程式支援此功能。

Windows 8.1Windows 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

另請參閱

時間值

WSAAsyncSelect

WSAEventSelect

Winsock 函數

Winsock 參考

接受

connect

recv

recv來自