select function (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 參數僅包含以與 Vari 套接字相容。

[in, out] readfds

要檢查一組套接字的選擇性指標,以取得可讀性。

[in, out] writefds

要檢查一組套接字的選擇性指標,以取得可寫入性。

[in, out] exceptfds

要檢查錯誤之一組套接字的選擇性指標。

[in] timeout

選取等候的時間上限,以 TIMEVAL 結構的形式提供。 將 逾時 參數設定為 null 以進行封鎖作業。

傳回值

select 函式會傳回已就緒且包含在fd_set結構中的套接字句柄總數,如果時間限制已過期,則傳回零,或發生錯誤時SOCKET_ERROR。 如果傳回值SOCKET_ERROR,可以使用 WSAGetLastError 來擷取特定的錯誤碼。

錯誤碼 意義
WSANOTINITIALISED
使用此函式之前,必須先進行成功的 WSAStartup 呼叫。
WSAEFAULT
Windows Sockets 實作無法為其內部作業配置所需的資源,或 readfds、writefdsexceptfdstimeval 參數不是使用者地址空間的一部分。
WSAENETDOWN
網路子系統失敗。
WSAEINVAL
逾時值無效,或所有三個描述項參數都是 Null
WSAEINTR
封鎖的 Windows Socket 1.1 呼叫已透過 WSACancelBlockingCall 取消。
WSAEINPROGRESS
封鎖的 Windows Sockets 1.1 呼叫正在進行中,或者服務提供者仍在處理回呼函式。
WSAENOTSOCK
其中一個描述項集合包含不是套接字的專案。

備註

select 函式可用來判斷一或多個套接字的狀態。 針對每個套接字,呼叫端可以要求讀取、寫入或錯誤狀態的相關信息。 要求指定狀態的套接字集是由 fd_set 結構表示。 包含在 fd_set 結構的套接字必須與單一服務提供者相關聯。 為了達到此限制的目的,如果描述其通訊協定的 WSAPROTOCOL_INFO 結構具有相同 providerId 值,則套接字會被視為來自相同的服務提供者。 傳回時,結構會更新,以反映符合指定條件的這些套接字子集。 select 函式會傳回符合條件的套接字數目。 提供一組宏來操作 fd_set 結構。 這些宏與一般軟體中使用的宏相容,但基礎表示法完全不同。

參數 readfds 會識別要檢查是否有可讀性的套接字。 如果套接字目前處於 接聽 狀態,如果收到傳入連線要求,因此保證 接受 完成而不封鎖,則會將其標示為可讀取。 若為其他套接字,可讀性表示佇列數據可供讀取,因此保證不會封鎖對 recvWSARecvFromrecvfrom 的呼叫。

針對連線導向套接字,可讀性也可以指出已從對等接收關閉套接字的要求。 如果虛擬線路已正常關閉,而且收到所有數據,則 recv 會立即傳回,且讀取的位元組為零。 如果虛擬線路已重設, 則 recv 會立即完成,並出現錯誤碼,例如 WSAECONNRESET。 如果套接字選項SO_OOBINLINE已啟用,則會檢查 OOB 數據是否存在, (請參閱 setockopt) 。

參數 writefd 會 識別要檢查的套接字是否可寫入。 如果套接字正在處理 連線 呼叫 (非封鎖) ,如果連線建立成功完成,就會寫入套接字。 如果套接字未處理 連線 呼叫,可寫入性表示 傳送sendtoWSASendto 保證會成功。 不過,如果 len 參數超過可用的傳出系統緩衝區空間數量,他們可以封鎖封鎖套接字。 它未指定可假設這些保證有效的時間長度,特別是在多線程環境中。

參數 exceptfds 會識別要檢查 OOB 數據是否存在或任何例外狀況的套接字。

注意 只有在選項SO_OOBINLINE為 FALSE 時,才會以這種方式報告頻外數據。 如果套接字正在處理 連線 呼叫 (非封鎖) , 則連線 嘗試失敗會在例外狀況 (應用程式中指出,然後呼叫 getsockopt SO_ERROR,以判斷錯誤值,以描述失敗發生的原因) 。 本檔未定義將包含哪些其他錯誤。
 
任何兩個參數 readfdswritefdsexceptfds 都可以指定為 null。 至少一個必須是非 Null,而且任何非 Null 描述元集合都必須至少包含套接字的一個句柄。

總而言之, 當選取 傳回下列情況時,將會在特定集合中識別套接字:

readfds

  • 如果已呼叫 接聽 ,且連線擱置中, 接受 將會成功。
  • 如果) 啟用SO_OOBINLINE,則數據可供讀取 (包含 OOB 數據。
  • 線上已關閉/重設/終止。
writefds
  • 如果處理 連線 呼叫 (非封鎖) ,則連線已成功。
  • 可以傳送數據。
exceptfds
  • 如果處理 連線 呼叫 (非封鎖) ,則連線嘗試失敗。
  • 只有在停用 SO_OOBINLINE 時,OOB 數據才能讀取) (。
在頭檔 Winsock2.h 中定義了四個宏,用於操作和檢查描述元集合。 變數FD_SETSIZE決定集合中描述項的最大數目。 (FD_SETSIZE 的預設值為 64,在包含 Winsock2.h.) 內部之前,定義FD_SETSIZE另一個值, fd_set 結構中的 套接字句柄不會以位旗標表示為 Count Unix。 其數據表示不透明。 使用這些宏可維護不同套接字環境之間的軟體可移植性。 要操作和檢查 fd_set 內容的宏如下:
  • FD_ZERO (*set) - 初始化設為空集。 使用之前,應該一律清除集合。
  • FD_CLR (s,*set) - 移除集合中的套接字。
  • FD_ISSET (s、*set) - 檢查 s 是否為 set 的成員,並傳回 TRUE。
  • FD_SET (s,*set) - 新增要設定的套接字。

參數 逾時 可控制 選取 可能需要多少時間才能完成。 如果 逾時Null 指標, 選取 將會無限期地封鎖,直到至少有一個描述元符合指定的準則為止。 否則, 逾時 會指向 TIMEVAL 結構,指定 選取 在傳回之前應該等候的時間上限。 選取傳回時,不會改變 TIMEVAL 結構的內容。 如果 TIMEVAL 初始化為 {0, 0}, 選取 將會立即傳回;這是用來輪詢所選套接字的狀態。 如果 select 立即傳回,則會將 選取 呼叫視為非封鎖,而且會套用非封鎖呼叫的標準假設。 例如,不會呼叫封鎖勾點,而且不會產生 Windows Sockets。

注意select 函式不會影響向 WSAAsyncSelectWSAEventSelect 註冊的套接字事件持續性。
 
注意 發出封鎖的 Winsock 呼叫時,例如 select 並將 timeout 參數設定為 NULL 時,Winsock 可能需要等候網路事件,才能完成呼叫。 Winsock 會在這種情況中執行可警示的等候,而異步過程調用 (APC) 排程在同一個線程上,可能會中斷。 在 APC 內發出另一個封鎖 Winsock 呼叫,中斷相同線程上持續封鎖 Winsock 呼叫會導致未定義的行為,而且永遠不會由 Winsock 客戶端嘗試。
 
Windows Phone 8:Windows Phone 8 和更新版本上的 Windows Phone Store 應用程式支援此函式。

Windows 8.1Windows Server 2012 R2:Windows 8.1、Windows Server 2012 R2 及更新版本上的 Windows 市集應用程式支援此函式。

規格需求

   
最低支援的用戶端 Windows 8.1、Windows Vista [傳統型應用程式 |UWP 應用程式]
最低支援的伺服器 Windows Server 2003 [傳統型應用程式 |UWP 應用程式]
目標平台 Windows
標頭 winsock2.h
程式庫 Ws2_32.lib
Dll Ws2_32.dll

另請參閱

TIMEVAL

WSAAsyncSelect

WSAEventSelect

Winsock 函式

Winsock 參考

接受

connect

recv

recvfrom

send