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 運算元搭配任何這些值來建構。
價值 | 意義 |
---|---|
|
發出讀取整備的通知。 |
|
發出準備寫入的通知。 |
|
發出 OOB 數據抵達的通知。 |
|
發出連入連線的通知。 |
|
發出已完成連線的通知。 |
|
發出套接字關閉通知。 |
|
發出套接字服務品質(QoS)變更通知。 |
|
保留。 |
|
發出指定目的地路由介面變更的通知。 |
|
發出套接字通訊協定系列之本機位址清單變更的通知。 |
[out] lpErrno
錯誤碼的指標。 如需詳細資訊,請參閱 傳回值 一節。
傳回值
如果 Windows Sockets SPI 用戶端對網路事件集感興趣的宣告成功,則傳回值為零。 否則,會傳回SOCKET_ERROR值,而且 lpErrno中提供特定的錯誤碼。
錯誤碼 | 意義 |
---|---|
網路子系統失敗。 | |
表示其中一個指定的參數無效,例如未參考現有視窗的視窗句柄,或指定的套接字處於無效狀態。 | |
封鎖的 Windows Sockets 呼叫正在進行中,或服務提供者仍在處理回呼函式。 | |
描述元不是套接字。 |
如需可在應用程式視窗收到訊息時設定的其他錯誤碼資訊,請參閱,以取得可設定的其他錯誤碼資訊(在訊息內 lParam 的高字)。
言論
每當服務提供者偵測到 lEvent 自變數所指定的任何網路事件時,此函式會用來要求服務提供者將 Windows 訊息傳送至用戶端的視窗 hWnd。 服務提供者應該使用 WPUPostMessage 函式來張貼訊息。 要傳送的訊息是由 wMsg 參數
不論 lEvent
叫用套接字的 LPWSPAsyncSelect 會取消任何先前的 LPWSPAsyncSelect 或 LPWSPEventSelect 相同的套接字。 例如,若要同時接收讀取和寫入的通知,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
錯誤碼 | 意義 |
---|---|
指定系列中的位址無法與這個套接字搭配使用。 | |
嘗試連線遭到拒絕。 | |
目前無法從此主機連線到網路。 | |
namelen 參數無效。 | |
套接字已系結至位址。 | |
套接字已連線。 | |
沒有其他檔案描述項可供使用。 | |
沒有可用的緩衝區空間。 套接字無法連接。 | |
套接字未連線。 | |
嘗試連線逾時,而不建立連線。 |
事件:FD_CLOSE
錯誤碼 | 意義 |
---|---|
網路子系統失敗。 | |
線上已由遠端端重設。 | |
線上因為逾時或其他失敗而終止。 |
事件...:FD_ACCEPT、FD_ADDRESS_LIST_CHANGE、FD_GROUP_QOS、FD_OOB、FD_QOS、FD_READ、FD_WRITE
錯誤碼 | 意義 |
---|---|
網路子系統失敗。 |
事件:FD_ROUTING_INTERFACE_CHANGE
錯誤碼 | 意義 |
---|---|
指定的目的地已無法再連線。 | |
網路子系統失敗。 |
雖然 LPWSPAsyncSelect 可以與多個事件感興趣而呼叫,但服務提供者會針對每個事件發出相同的 Windows 訊息。
Windows Sockets 2 提供者不應該持續向 Windows Sockets SPI 用戶端填滿特定網路事件的訊息。 成功將特定事件的通知張貼到 Windows Sockets SPI 用戶端窗口之後,該網路事件的進一步訊息將不會張貼到 Windows Sockets SPI 用戶端視窗,直到 Windows Sockets SPI 用戶端發出函式呼叫,以隱含方式重新啟用該網路事件的通知。
網路事件 | 重新啟用函式 |
---|---|
FD_READ | LPWSPRecv 或 LPWSPRecvFrom |
FD_WRITE | LPWSPSend 或 LPWSPSendTo |
FD_OOB | LPWSPRecv 或 LPWSPRecvFrom |
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時發生任何事件,或呼叫重新啟用函式時,則會視需要張貼訊息。 例如,請考慮下列順序。
- Windows Sockets SPI 用戶端會呼叫 LPWSPListen。
- 收到連線要求,但尚未接受。
- Windows Sockets SPI 用戶端會呼叫 LPWSPAsyncSelect 指定它想要接收套接字FD_ACCEPT訊息。 由於事件的持續性,WinSock 服務提供者會立即張貼FD_ACCEPT訊息。
FD_WRITE事件會以稍微不同的方式處理。 當套接字第一次連接 LPWSPConnect 時,就會張貼FD_WRITE訊息(FD_CONNECT之後, 如果也已註冊)或接受 LPWSPAccept,然後在 LPWSPSend 或 LPWSPSendTo 失敗,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
FD_ADDRESS_LIST_CHANGE訊息會在發出 SIO_ADDRESS_LIST_CHANGE
以下是每個異步通知訊息的事件和條件摘要。
FD_READ
- 呼叫 LPWSPAsyncSelect 時,如果有數據目前可供接收。
- 當數據送達時,如果FD_READ尚未張貼。
- LPWSPRecv 或 LPWSPRecvFrom 呼叫後 MSG_PEEK,如果數據仍可供接收,則為 。
啟用 LPWSPSetSockOpt SO_OOBINLINE 時,數據 包含上述實例中的一般數據和頻外 (OOB) 數據。
FD_WRITE
- 呼叫 LPWSPAsyncSelect 時,如果 LPWSPSend 或 LPWSPSendTo。
- 在 LPWSPConnect 或 LPWSPAccept 建立連線時呼叫之後。
- LPWSPSend 或 LPWSPSendTo WSAEWOULDBLOCK 失敗之後,LPWSPSend 或 LPWSPSendTo 可能會成功。
- 在無連線套接字上 LPWSPBind 之後。 FD_WRITE目前可能或可能不會發生 (實作相依)。 在任何情況下,LPWSPBind之後,一律會立即寫入無連線套接字。
FD_OOB (只有在停用 LPWSPSetSockOpt SO_OOBINLINE 時才有效 (預設值)
- 呼叫 LPWSPAsyncSelect 時,如果有 OOB 數據目前可使用 MSG_OOB 旗標接收。
- 當 OOB 數據送達時,如果FD_OOB尚未張貼。
- LPWSPRecv 或 LPWSPRecvFrom 之後,如果 OOB 數據仍可供接收,則會使用或不使用 MSG_OOB 旗標來呼叫。
FD_ACCEPT
- 當呼叫 LPWSPAsyncSelect 時,如果有連線要求可供接受。
- 當連線要求送達時,如果尚未張貼FD_ACCEPT。
- 呼叫 LPWSPAccept 之後,如果有另一個連線要求可供接受。
FD_CONNECT
- 呼叫 LPWSPAsyncSelect 時,如果目前已建立連線。
- 呼叫 LPWSPConnect 之後,當建立連線時(即使 LPWSPConnect 會立即成功,就像數據報套接字一般一樣),即使它立即失敗也一樣)。
- 呼叫 WSPJoinLeaf 之後,當聯結作業完成時。
- 連線之後,WSAConnect或 WSPJoinLeaf 使用非封鎖、聯機導向的套接字呼叫。 初始作業傳回時發生 WSAEWOULDBLOCK 的特定錯誤,但網路作業繼續進行。 作業最終是否成功,當結果已決定時,FD_CONNECT發生。 客戶端應該檢查錯誤碼,以判斷結果是否成功或失敗。
FD_CLOSE (僅適用於連線導向套接字 (例如,SOCK_STREAM)
- 呼叫 LPWSPAsyncSelect 時,如果套接字連線已關閉。
- 在遠端系統起始正常關閉之後,當目前沒有數據可供接收時(如果已收到數據,且在遠端系統起始正常關閉時等候讀取,則FD_CLOSE在讀取所有擱置的數據之前不會傳遞)。
- 當目前沒有數據可供接收時,本機系統會啟動 LPWSPShutdown 且遠端系統已回應 端數據 通知(例如 TCP FIN)的正常關閉之後。
- 當遠端系統中止連線時(例如傳送 TCP RST),且 lParam 將包含 WSAECONNRESET 錯誤值。
FD_CLOSE不會在 呼叫 LPWSPCloseSocket 之後張貼。
FD_QOS
- 呼叫 LPWSPAsyncSelect 時,如果已變更與套接字相關聯的 QOS。
- 呼叫具有 SIO_GET_QOS 的 LPWSPIoctl LPWSPIoctl 之後,當 QOS 變更時。
FD_GROUP_QOS
保留供未來搭配套接字群組使用:
- 呼叫 LPWSPAsyncSelect 時,如果已變更與套接字相關聯的群組 QOS。
- 呼叫 LPWSPIoctl 並呼叫 SIO_GET_GROUP_QOS 之後,當群組 QOS 變更時。
FD_ROUTING_INTERFACE_CHANGE
- 呼叫 LPWSPIoctl SIO_ROUTING_INTERFACE_CHANGE 之後,當應該用來連線到 IOCTL 中指定的目的地時,就會呼叫本機介面。
FD_ADDRESS_LIST_CHANGE
- 呼叫 LPWSPIoctl SIO_ADDRESS_LIST_CHANGE 之後,當 Windows Sockets SPI 用戶端可以繫結變更的本機地址清單時。
要求
要求 | 價值 |
---|---|
最低支援的用戶端 | Windows 10 組建 20348 |
支援的最低伺服器 | Windows 10 組建 20348 |
標頭 | ws2spi.h |