LPWSPASYNCSELECT 回調函式 (ws2spi.h)

LPWSPAsyncSelect 函式會要求 Windows 訊息型事件通知套接字的網路事件。

語法

LPWSPASYNCSELECT Lpwspasyncselect;

int Lpwspasyncselect(
  [in]  SOCKET s,
  [in]  HWND hWnd,
  [in]  unsigned int wMsg,
  [in]  long lEvent,
  [out] LPINT lpErrno
)
{...}

參數

[in] s

識別需要事件通知之套接字的描述項。

[in] hWnd

處理識別在發生網路事件時應接收訊息的視窗。

[in] wMsg

發生網路事件時要傳送的訊息。

[in] lEvent

位掩碼,指定 Windows Sockets 服務提供者介面 (SPI) 用戶端感興趣的網路事件組合。 使用位 OR 運算元搭配任何這些值來建構。

價值 意義
FD_READ
發出讀取整備的通知。
FD_WRITE
發出準備寫入的通知。
FD_OOB
發出 OOB 數據抵達的通知。
FD_ACCEPT
發出連入連線的通知。
FD_CONNECT
發出已完成連線的通知。
FD_CLOSE
發出套接字關閉通知。
FD_QOS
發出套接字服務品質(QoS)變更通知。
FD_GROUP_QOS
保留。
FD_ROUTING_INTERFACE_CHANGE
發出指定目的地路由介面變更的通知。
FD_ADDRESS_ LIST_CHANGE
發出套接字通訊協定系列之本機位址清單變更的通知。

[out] lpErrno

錯誤碼的指標。 如需詳細資訊,請參閱 傳回值 一節。

傳回值

如果 Windows Sockets SPI 用戶端對網路事件集感興趣的宣告成功,則傳回值為零。 否則,會傳回SOCKET_ERROR值,而且 lpErrno中提供特定的錯誤碼。

錯誤碼 意義
WSAENETDOWN
網路子系統失敗。
WSAEINVAL
表示其中一個指定的參數無效,例如未參考現有視窗的視窗句柄,或指定的套接字處於無效狀態。
WSAEINPROGRESS
封鎖的 Windows Sockets 呼叫正在進行中,或服務提供者仍在處理回呼函式。
WSAENOTSOCK
描述元不是套接字。

如需可在應用程式視窗收到訊息時設定的其他錯誤碼資訊,請參閱,以取得可設定的其他錯誤碼資訊(在訊息內 lParam 的高字)。

言論

每當服務提供者偵測到 lEvent 自變數所指定的任何網路事件時,此函式會用來要求服務提供者將 Windows 訊息傳送至用戶端的視窗 hWnd。 服務提供者應該使用 WPUPostMessage 函式來張貼訊息。 要傳送的訊息是由 wMsg 參數 所指定。 識別需要通知的套接字。

不論 lEvent的值為何,此函式會自動將套接字 s 設定為非封鎖模式。 請參閱 LPWSPIoctl 瞭解如何將套接字設定回封鎖模式。

叫用套接字的 LPWSPAsyncSelect 會取消任何先前的 LPWSPAsyncSelectLPWSPEventSelect 相同的套接字。 例如,若要同時接收讀取和寫入的通知,Windows Sockets SPI 用戶端必須呼叫 LPWSPAsyncSelect,FD_READ和FD_WRITE,如下所示。

rc = WSPAsyncSelect(s, hWnd, wMsg, FD_READ | FD_WRITE, &error);

無法為不同的事件指定不同的訊息。 下列程式代碼無法運作;第二個呼叫會取消第一個的效果,唯一的關聯將是與 wMsg2 相關聯的FD_WRITE事件。

// Incorrect example.
rc = WSPAsyncSelect(s, hWnd, wMsg1, FD_READ, &error);
rc = WSPAsyncSelect(s, hWnd, wMsg2, FD_WRITE, &error);

若要取消所有通知(也就是,表示服務提供者不應傳送與套接字上網路事件相關的進一步訊息),請將 lEvent 設為零。

rc = WSPAsyncSelect(s, hWnd, 0, 0, &error);

由於 LPWSPAccept'ed 套接字具有與用來接受的接聽套接字相同的屬性,因此任何 為接聽套接字設定的 LPWSPAsyncSelect 事件都會套用至接受的套接字。 例如,如果接聽套接字 LPWSPAsyncSelect 事件FD_ACCEPT、FD_READ和FD_WRITE,則該接聽套接字上接受的任何套接字也會有FD_ACCEPT、FD_READ和FD_WRITE事件,且具有用於訊息的相同 wMsg 值。 如果需要不同的 wMsg 或事件,則 Windows Sockets SPI 用戶端應該呼叫 LPWSPAsyncSelect、傳遞接受的套接字,以及所需的新資訊。

當指定的套接字 發生其中一個指定的網路事件時,服務提供者會使用 WPUPostMessage,將訊息 wMsg 傳送至 Windows Sockets SPI 用戶端的視窗,hWnd。 在張貼的訊息中,wParam 自變數會識別發生網路事件的套接字。 lParam 低字 會指定已發生的網路事件。 可能指出的網路事件代碼如下所示。

價值 意義
FD_READ 套接字 已準備好讀取
FD_WRITE 套接字 已準備好寫入
FD_OOB 頻外數據已準備好在套接字 讀取
FD_ACCEPT 套接字 已準備好接受新的連入連線
FD_CONNECT 套接字 上起始的連線已完成
FD_CLOSE 套接字 所識別的連接已關閉
FD_QOS 與套接字 相關聯的服務品質已變更
FD_GROUP_QOS 保留供套接字群組日後使用:與套接字群組相關聯的服務品質已變更套接字 所屬的套接字群組
FD_ROUTING_INTERFACE_CHANGE 應該用來傳送至指定目的地的本機介面已變更
FD_ADDRESS_LIST_CHANGE Windows Sockets SPI 用戶端可以系結的套接字通訊協定系列位址清單已變更

lParam 的高字包含任何錯誤碼(可以使用 WSAGETSELECTERROR 宏來擷取)。 錯誤碼是 ws2spi.h中所定義的任何錯誤。 下表列出每個網路事件的可能錯誤碼。

事件:FD_CONNECT

錯誤碼 意義
WSAEAFNOSUPPORT
指定系列中的位址無法與這個套接字搭配使用。
WSAECONNREFUSED
嘗試連線遭到拒絕。
WSAENETUNREACH
目前無法從此主機連線到網路。
WSAEFAULT
namelen 參數無效。
WSAEINVAL
套接字已系結至位址。
WSAEISCONN
套接字已連線。
WSAEMFILE
沒有其他檔案描述項可供使用。
WSAENOBUFS
沒有可用的緩衝區空間。 套接字無法連接。
WSAENOTCONN
套接字未連線。
WSAETIMEDOUT
嘗試連線逾時,而不建立連線。

事件:FD_CLOSE

錯誤碼 意義
WSAENETDOWN
網路子系統失敗。
WSAECONNRESET
線上已由遠端端重設。
WSAECONNABORTED
線上因為逾時或其他失敗而終止。

事件...:FD_ACCEPT、FD_ADDRESS_LIST_CHANGE、FD_GROUP_QOS、FD_OOB、FD_QOS、FD_READ、FD_WRITE

錯誤碼 意義
WSAENETDOWN
網路子系統失敗。

事件:FD_ROUTING_INTERFACE_CHANGE

錯誤碼 意義
WSAENETUNREACH
指定的目的地已無法再連線。
WSAENETDOWN
網路子系統失敗。

雖然 LPWSPAsyncSelect 可以與多個事件感興趣而呼叫,但服務提供者會針對每個事件發出相同的 Windows 訊息。

Windows Sockets 2 提供者不應該持續向 Windows Sockets SPI 用戶端填滿特定網路事件的訊息。 成功將特定事件的通知張貼到 Windows Sockets SPI 用戶端窗口之後,該網路事件的進一步訊息將不會張貼到 Windows Sockets SPI 用戶端視窗,直到 Windows Sockets SPI 用戶端發出函式呼叫,以隱含方式重新啟用該網路事件的通知。

網路事件 重新啟用函式
FD_READ LPWSPRecvLPWSPRecvFrom
FD_WRITE LPWSPSendLPWSPSendTo
FD_OOB LPWSPRecvLPWSPRecvFrom
FD_ACCEPT LPWSPAccept,除非傳回的錯誤碼WSATRY_AGAIN指出條件函式傳回CF_DEFER
FD_CONNECT 沒有
FD_CLOSE 沒有
FD_QOS LPWSPIoctl 與 SIO_GET_QOS
FD_GROUP_QOS 保留供未來搭配套接字群組使用:LPWSPIoctl 搭配 SIO_GET_GROUP_QOS
FD_ROUTING_INTERFACE_CHANGE 使用命令SIO_ROUTING_INTERFACE_CHANGE LPWSPIoctl
FD_ADDRESS_LIST_CHANGE 使用命令SIO_ADDRESS_LIST_CHANGE LPWSPIoctl

重新啟用例程的任何呼叫,即使是失敗的例程,都會導致重新啟用相關事件的訊息張貼。

針對FD_READ、FD_OOB和FD_ACCEPT事件,訊息張貼 層級觸發。 這表示,如果呼叫重新啟用例程,且呼叫之後仍符合相關條件,則會將 LPWSPAsyncSelect 訊息張貼至 Windows Sockets SPI 用戶端。

FD_QOS與FD_GROUP_QOS事件會視為 邊緣觸發。 當 QOS 變更發生時,只會張貼訊息一次。 在提供者偵測到 QOS 中的進一步變更,或 Windows Sockets SPI 用戶端重新談判套接字的 QOS 之前,才會發出進一步的訊息。

FD_ROUTING_INTERFACE_CHANGE和FD_ADDRESS_LIST_CHANGE事件也會視為 邊緣觸發。 Windows Sockets SPI 用戶端發出 WSAIoctl,並對應發出SIO_ROUTING_INTERFACE_CHANGE或SIO_ADDRESS_LIST_CHANGE來要求通知時,只會張貼一次訊息。 在 Windows Sockets SPI 用戶端重新發出 IOCTL ,並 偵測到自 IOCTL 發出之後,偵測到另一個變更之後,才會發出進一步訊息。

如果 Windows Sockets SPI 用戶端呼叫 LPWSPAsyncSelect時發生任何事件,或呼叫重新啟用函式時,則會視需要張貼訊息。 例如,請考慮下列順序。

  1. Windows Sockets SPI 用戶端會呼叫 LPWSPListen
  2. 收到連線要求,但尚未接受。
  3. Windows Sockets SPI 用戶端會呼叫 LPWSPAsyncSelect 指定它想要接收套接字FD_ACCEPT訊息。 由於事件的持續性,WinSock 服務提供者會立即張貼FD_ACCEPT訊息。

FD_WRITE事件會以稍微不同的方式處理。 當套接字第一次連接 LPWSPConnect 時,就會張貼FD_WRITE訊息(FD_CONNECT之後, 如果也已註冊)或接受 LPWSPAccept,然後在 LPWSPSendLPWSPSendTo 失敗,WSAEWOULDBLOCK 和緩衝區空間變成可用。 因此,Windows Sockets SPI 用戶端可以假設從第一個FD_WRITE訊息開始傳送,直到傳送傳回 WSAEWOULDBLOCK 為止。 發生這類失敗之後,Windows Sockets SPI 用戶端會收到通知,指出傳送會再次收到FD_WRITE訊息。

只有當套接字設定為個別接收頻外數據時,才會使用FD_OOB事件。 如果套接字設定為內嵌接收頻外數據,則會將頻外(加速)數據視為一般數據,而 Windows Sockets SPI 用戶端必須註冊對FD_READ事件的興趣,而不是FD_OOB事件。

FD_CLOSE訊息中的錯誤碼指出套接字關閉是否正常或中止。 如果錯誤碼為 0,則關閉是正常;如果錯誤碼為 WSAECONNRESET,則會重設套接字的虛擬線路。 這隻適用於連線導向的套接字,例如SOCK_STREAM。

收到對應至套接字之虛擬線路的關閉指示時,會張貼FD_CLOSE訊息。 在 TCP 方面,這表示當連線進入 TIME WAIT 或 CLOSE WAIT 狀態時,就會張貼FD_CLOSE。 這會導致遠端端在傳送端或 LPWSPCloseSocket上執行 LPWSPShutdown。 只有在從套接字讀取所有數據之後,才會張貼FD_CLOSE是正確的。

在正常關閉的情況下,服務提供者應該傳送FD_CLOSE訊息,表示只有在讀取所有已接收的數據之後,才會關閉虛擬線路。 它不應該傳送FD_READ訊息來指出此條件。

FD_QOS或FD_GROUP_QOS訊息會在流程規格中變更與套接字 相關聯的任何字段,或 所屬的套接字群組時,張貼訊息。 服務提供者必須使用 SIO_GET_QOS 和/或 SIO_GET_GROUP_QOS,透過 LPWSPIoctl 更新用戶端可用的 QOS 資訊。

FD_ROUTING_INTERFACE_CHANGE訊息會在發出這類 IOCTL 之後,以SIO_ROUTING_INTERFACE_CHANGE 變更 LPWSPIoctl 中所指定的目的地時,張貼FD_ROUTING_INTERFACE_CHANGE訊息。

FD_ADDRESS_LIST_CHANGE訊息會在發出 SIO_ADDRESS_LIST_CHANGELPWSPIoctl 之後,Windows Sockets SPI 用戶端可以系結變更 位址清單時張貼。

以下是每個異步通知訊息的事件和條件摘要。

FD_READ

  1. 呼叫 LPWSPAsyncSelect 時,如果有數據目前可供接收。
  2. 當數據送達時,如果FD_READ尚未張貼。
  3. LPWSPRecvLPWSPRecvFrom 呼叫後 MSG_PEEK,如果數據仍可供接收,則為 。

啟用 LPWSPSetSockOpt SO_OOBINLINE 時,數據 包含上述實例中的一般數據和頻外 (OOB) 數據。

FD_WRITE

  1. 呼叫 LPWSPAsyncSelect 時,如果 LPWSPSendLPWSPSendTo
  2. LPWSPConnectLPWSPAccept 建立連線時呼叫之後。
  3. LPWSPSendLPWSPSendTo WSAEWOULDBLOCK 失敗之後,LPWSPSendLPWSPSendTo 可能會成功。
  4. 在無連線套接字上 LPWSPBind 之後。 FD_WRITE目前可能或可能不會發生 (實作相依)。 在任何情況下,LPWSPBind之後,一律會立即寫入無連線套接字。

FD_OOB (只有在停用 LPWSPSetSockOpt SO_OOBINLINE 時才有效 (預設值)

  1. 呼叫 LPWSPAsyncSelect 時,如果有 OOB 數據目前可使用 MSG_OOB 旗標接收。
  2. 當 OOB 數據送達時,如果FD_OOB尚未張貼。
  3. LPWSPRecvLPWSPRecvFrom 之後,如果 OOB 數據仍可供接收,則會使用或不使用 MSG_OOB 旗標來呼叫。

FD_ACCEPT

  1. 當呼叫 LPWSPAsyncSelect 時,如果有連線要求可供接受。
  2. 當連線要求送達時,如果尚未張貼FD_ACCEPT。
  3. 呼叫 LPWSPAccept 之後,如果有另一個連線要求可供接受。

FD_CONNECT

  1. 呼叫 LPWSPAsyncSelect 時,如果目前已建立連線。
  2. 呼叫 LPWSPConnect 之後,當建立連線時(即使 LPWSPConnect 會立即成功,就像數據報套接字一般一樣),即使它立即失敗也一樣)。
  3. 呼叫 WSPJoinLeaf 之後,當聯結作業完成時。
  4. 連線之後,WSAConnectWSPJoinLeaf 使用非封鎖、聯機導向的套接字呼叫。 初始作業傳回時發生 WSAEWOULDBLOCK 的特定錯誤,但網路作業繼續進行。 作業最終是否成功,當結果已決定時,FD_CONNECT發生。 客戶端應該檢查錯誤碼,以判斷結果是否成功或失敗。

FD_CLOSE (僅適用於連線導向套接字 (例如,SOCK_STREAM)

  1. 呼叫 LPWSPAsyncSelect 時,如果套接字連線已關閉。
  2. 在遠端系統起始正常關閉之後,當目前沒有數據可供接收時(如果已收到數據,且在遠端系統起始正常關閉時等候讀取,則FD_CLOSE在讀取所有擱置的數據之前不會傳遞)。
  3. 當目前沒有數據可供接收時,本機系統會啟動 LPWSPShutdown 且遠端系統已回應 端數據 通知(例如 TCP FIN)的正常關閉之後。
  4. 當遠端系統中止連線時(例如傳送 TCP RST),且 lParam 將包含 WSAECONNRESET 錯誤值。

FD_CLOSE不會在 呼叫 LPWSPCloseSocket 之後張貼。

FD_QOS

  1. 呼叫 LPWSPAsyncSelect 時,如果已變更與套接字相關聯的 QOS。
  2. 呼叫具有 SIO_GET_QOS 的 LPWSPIoctl LPWSPIoctl 之後,當 QOS 變更時。

FD_GROUP_QOS

保留供未來搭配套接字群組使用:

  1. 呼叫 LPWSPAsyncSelect 時,如果已變更與套接字相關聯的群組 QOS。
  2. 呼叫 LPWSPIoctl 並呼叫 SIO_GET_GROUP_QOS 之後,當群組 QOS 變更時。

FD_ROUTING_INTERFACE_CHANGE

  1. 呼叫 LPWSPIoctl SIO_ROUTING_INTERFACE_CHANGE 之後,當應該用來連線到 IOCTL 中指定的目的地時,就會呼叫本機介面。

FD_ADDRESS_LIST_CHANGE

  1. 呼叫 LPWSPIoctl SIO_ADDRESS_LIST_CHANGE 之後,當 Windows Sockets SPI 用戶端可以繫結變更的本機地址清單時。

要求

要求 價值
最低支援的用戶端 Windows 10 組建 20348
支援的最低伺服器 Windows 10 組建 20348
標頭 ws2spi.h

另請參閱

LPWSPAsyncSelect 回呼函式