共用方式為


Protocol-Independent 頻外數據

數據流套接字抽象概念包含頻外數據的概念。 許多通訊協定可讓傳入數據的某些部分以某種方式標示為特殊,而且這些特殊數據區塊可傳送給使用者,使其脫離一般序列。 範例包括 X.25 和其他 OSI 通訊協定中的加速數據,以及 BSD UNIX 使用 TCP 的緊急數據。 下一節說明 OOB 數據處理方式與通訊協議無關。 使用 TCP 緊急數據實作的 OOB 資料討論會遵循與通訊協定無關的說明。 在每個討論中,使用 recv 也表示 recvfromWSARecvWSARecvFrom,以及 WSAAsyncSelect 的參考也適用於 WSAEventSelect

通訊協議獨立 OOB 數據

OOB 數據是與每對連線數據流套接字相關聯的邏輯獨立傳輸通道。 OOB 數據可能會與一般數據無關,傳送給使用者。 抽象概念定義 OOB 數據設施必須支援一次至少一個 OOB 數據區塊的可靠傳遞。 此數據區塊可以包含至少一個字節的數據,而且至少一個 OOB 數據區塊可以隨時擱置傳送給使用者。 對於支援頻內訊號的通訊通訊協定(例如 TCP,其中緊急數據會依正常數據依序傳遞),系統通常會從一般數據流擷取 OOB 數據,並將它分開儲存(在一般數據流中留下空白)。 這可讓使用者選擇依序接收 OOB 數據,以及依序接收 OOB 數據,而不需要緩衝處理所有介入的數據。 可以窺視頻外 (OOB) 數據。

使用者可以使用 ioctlsocketWSAIoctl 函式搭配 SIOCATMARK IOCTL,判斷是否有任何 OOB 數據正在等候讀取。 對於 OOB 數據區塊在一般數據流中位置概念有意義的通訊協定,例如 TCP,Windows Sockets 服務提供者會維護概念標記,指出 OOB 數據在一般數據流中最後一個字節的位置。 ioctlsocket支援 SIOCATMARK 的 WSAIoctl 函式實作並非必要。 需要 OOB 數據存在或不存在。

對於 OOB 數據區塊在一般數據流中位置概念有意義的通訊協定,應用程式可能會將頻外數據內嵌處理為一般數據流的一部分。 使用 setockopt 函式設定套接字選項SO_OOBINLINE即可達成此目的。 對於 OOB 數據區塊真正獨立於一般數據流的其他通訊協定,嘗試設定SO_OOBINLINE會導致錯誤。 應用程式可以使用 ioctlsocketWSAIoctl 函式搭配 SIOCATMARK IOCTL,來判斷標記前面是否有任何未讀取的 OOB 數據。 例如,它可以使用這項資訊來重新同步處理其對等,方法是確保適當時捨棄數據流中標記的所有數據。

停用SO_OOBINLINE (預設設定):

  • 如果應用程式向 WSAAsyncSelect註冊通知,則 Windows Sockets 會通知應用程式FD_OOB事件,其方式與FD_READ用來通知正常數據是否存在的方式完全相同。 也就是說,當 OOB 數據送達且先前未排入佇列的 OOB 數據時,就會張貼FD_OOB。 當使用 MSG_OOB 旗標讀取數據時,也會張貼FD_OOB,而某些 OOB 數據在讀取作業傳回之後仍會排入佇列。 OOB 數據不會張貼FD_READ訊息。
  • Windows Sockets 會從 選取,如果 OOB 數據排入套接字佇列,請選取具有適當 例外狀況 套接字集。
  • 應用程式可以呼叫 recv,並隨時MSG_OOB讀取緊急數據區塊。 OOB 數據的區塊會跳躍佇列。
  • 應用程式可以呼叫 recv,而不需MSG_OOB讀取一般數據流。 OOB 數據區塊不會出現在具有一般數據的數據流中。 如果在呼叫 recv之後仍保留 OOB 數據,Windows Sockets 會在使用 select時,以 FD_OOB 或 exceptfds 通知應用程式。
  • 對於 OOB 數據在一般數據流中具有位置的通訊協定,單一 recv 作業不會跨越該位置。 一個 recv 會傳回標記之前的一般數據,而第二個 recv 則需要在標記之後開始讀取數據。

開啟SO_OOBINLINE:

  • OOB 數據不會張貼FD_OOB訊息。 OOB 數據會視為一般,以便 選取WSAAsyncSelect 函式,並以 readfds 或分別傳送FD_READ訊息來表示。
  • 應用程式無法呼叫 recv,並將 MSG_OOB 旗標設定為讀取 OOB 數據區塊。 傳回錯誤碼 WSAEINVAL。
  • 應用程式可以呼叫 recv,而不需設定MSG_OOB旗標。 任何 OOB 數據會在一般數據流內以正確的順序傳遞。 OOB 數據永遠不會與一般數據混合。 必須有三個讀取要求,才能超過 OOB 數據。 第一個傳回 OOB 數據區塊之前的一般數據,第二個傳回 OOB 數據,第三個傳回 OOB 數據之後的一般數據。 換句話說,會保留 OOB 數據區塊界限。

WSAAsyncSelect 例程特別適合處理SO_OOBINLINE關閉時出現頻外數據的通知。

TCP 中的 OOB 數據

重要

下列討論使用 TCP 緊急數據實作的頻外數據(OOB),遵循伯克利軟體發佈中使用的模型。 使用者和實作者應該注意:

 

  • 目前,RFC 793 兩個相互矛盾的解釋(其中引進了概念)。

  • Berkeley 軟體發佈 (BSD) 中的 OOB 數據實作不符合 RFC 1122 中所指定的主機需求。

    具體來說,BSD 中的 TCP 緊急指標會指向緊急數據位元組之後的位元組,而符合 RFC 規範的 TCP 緊急指標指向緊急數據位元組。 因此,如果應用程式將緊急數據從 BSD 相容的實作傳送至與 RFC 1122 相容的實作,接收者會讀取錯誤的緊急數據位元組(它會將位於數據流中正確位元組後面的位元組讀取為緊急數據位元組的位元組)。

    為了將互作性問題降到最低,除非這是與現有服務互作的必要專案,否則建議應用程式寫入器不要使用 OOB 數據。 敦促 Windows Sockets 供應商記錄其產品所實作的 OOB 語意(BSD 或 RFC 1122)。

TCP 區段的抵達與 URG(適用於緊急)旗標集,表示 TCP 數據流中存在單一 OOB 數據位元組。 OOB 數據區塊的大小為一個字節。 緊急指標是 TCP 標頭中目前序號的正位移,表示 OOB 數據區塊的位置(模棱兩可,如先前所述)。 因此,它可能會指向尚未收到的數據。

當包含緊急指標指向的位元組的 TCP 區段到達時,如果SO_OOBINLINE已停用 ,則會從數據流中移除 OOB 數據區塊(一個字節),並加以緩衝處理。 如果後續的 TCP 區段到達時加上緊急旗標集(以及新的緊急指標),則目前已排入佇列的 OOB 位元組可能會遺失,因為它會由新的 OOB 數據區塊取代(如 Berkeley Software Distribution 中所示)。 不過,它永遠不會在數據流中取代。

啟用SO_OOBINLINE後,緊急數據會保留在數據流中。 因此,當新的 TCP 區段送達包含緊急數據時,永遠不會遺失 OOB 數據區塊。 現有的 OOB 資料標記會更新為新的位置。

注意

設定SO_OOBINLINE套接字選項時,SIOCATMARK IOCTL 一律會傳回 TRUE,而 OOB 數據會以一般數據的形式傳回給使用者。