SIO_SET_COMPATIBILITY_MODE控制項程式碼

Description

SIO_SET_COMPATIBILITY_MODE控制程式代碼會要求網路堆疊如何處理特定行為,而預設處理行為方式可能會因 Windows 版本而異。

若要執行這項作業,請使用下列參數呼叫 WSAIoctlWSPIoctl 函 式。

int WSAIoctl(
  (socket) s,             // descriptor identifying a socket
  SIO_SET_COMPATIBILITY_MODE, // dwIoControlCode
  (LPVOID) lpvInBuffer,    // pointer to WSA_COMPATIBILITY_MODE struct
  (DWORD) cbInBuffer,      // length of input buffer
  NULL,         // output buffer
  0,       // size of output buffer
  (LPDWORD) lpcbBytesReturned,    // number of bytes returned
  (LPWSAOVERLAPPED) lpOverlapped,   // OVERLAPPED structure
  (LPWSAOVERLAPPED_COMPLETION_ROUTINE) lpCompletionRoutine,  // completion routine
);
int WSPIoctl(
  (socket) s,             // descriptor identifying a socket
  SIO_SET_COMPATIBILITY_MODE, // dwIoControlCode
  (LPVOID) lpvInBuffer,    // pointer to WSA_COMPATIBILITY_MODE struct
  (DWORD) cbInBuffer,      // length of input buffer
  NULL,         // output buffer
  0,       // size of output buffer
  (LPDWORD) lpcbBytesReturned,    // number of bytes returned
  (LPWSAOVERLAPPED) lpOverlapped,   // OVERLAPPED structure
  (LPWSAOVERLAPPED_COMPLETION_ROUTINE) lpCompletionRoutine,  // completion routine
  (LPWSATHREADID) lpThreadId,   // a WSATHREADID structure
  (LPINT) lpErrno   // a pointer to the error code.
);

參數

s

識別通訊端的描述項。

dwIoControlCode

作業的控制程式代碼。 使用此作業 SIO_SET_COMPATIBILITY_MODE

lpvInBuffer

輸入緩衝區的指標。 此參數應該指向 WSA_COMPATIBILITY_MODE 結構。

cbInBuffer

輸入緩衝區的大小,以位元組為單位。 此參數應該等於或大於lpvInBuffer參數所指向之WSA_COMPATIBILITY_MODE結構的大小。

lpvOutBuffer

輸出緩衝區的指標。 這個作業未使用此參數。

cbOutBuffer

輸出緩衝區的大小,以位元組為單位。 此參數必須設定為零。

lmicrosoftBytesReturned

變數的指標,接收儲存在輸出緩衝區中的資料大小,以位元組為單位。 這個傳回的參數會指向此作業的 DWORD 值為零 ,因為沒有輸出。

lpvOverlapped

WSAOVERLAPPED結構的指標。

如果 建立的 通訊端沒有重迭屬性,則會忽略 lpOverlapped 參數。

如果 已使用重迭屬性開啟 lpOverlapped 參數不是 Null,則會以重迭 (非同步) 作業來執行作業。 在此情況下, lpOverlapped 參數必須指向有效的 WSAOVERLAPPED 結構。

對於重迭的作業, WSAIoctlWSPIoctl 函式會立即傳回,並在作業完成時發出適當的完成方法訊號。 否則,函式不會在作業完成或發生錯誤之前傳回。

lpCompletionRoutine

類型:_In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE

當作業完成時呼叫的完成常式指標, (忽略非重迭通訊端) 。

lpThreadId

提供者後續呼叫WPUQueueApc時要使用的WSATHREADID結構的指標。 提供者應該儲存參考的 WSATHREADID 結構, (直到 WPUQueueApc 函式傳回之後,才儲存相同) 的指標。

注意 此參數僅適用于 WSPIoctl 函 式。

lpErrno

錯誤碼的指標。

注意 此參數僅適用于 WSPIoctl 函 式。

傳回值

如果作業順利完成, WSAIoctlWSPIoctl 函式會傳回零。

如果作業失敗或擱置中, WSAIoctlWSPIoctl 函式會 傳回SOCKET_ERROR。 若要取得擴充的錯誤資訊,請呼叫 WSAGetLastError

錯誤碼 意義
WSA_IO_PENDING 已成功起始重迭的作業,且稍後將會指出完成。
WSA_OPERATION_ABORTED 因為通訊端關閉或 SIO_FLUSH IOCTL 命令的執行,所以取消重迭的作業。
WSAEFAULT lpOverlappedlpCompletionRoutine參數未完全包含在使用者位址空間的有效部分中。
WSAEINPROGRESS 當回呼正在進行時,就會叫用函式。
WSAEINTR 封鎖作業已中斷。
WSAEINVAL dwIoControlCode參數不是有效的命令,或無法接受指定的輸入參數,或命令不適用於指定的通訊端類型。 如果 cbInBuffer 參數小於 WSA_COMPATIBILITY_MODE 結構的大小,就會傳回此錯誤。
WSAENETDOWN 網路子系統失敗。
WSAENOPROTOOPT 指定的通訊協定不支援通訊端選項。
WSAENOTCONN 通訊端未連接。
WSAENOTSOCK 描述項 s 不是通訊端。
WSAEOPNOTSUPP 不支援指定的 IOCTL 命令。 如果傳輸提供者不支援 SIO_SET_COMPATIBILITY_MODE IOCTL,就會傳回此錯誤。 當嘗試在資料包通訊端上使用 SIO_SET_COMPATIBILITY_MODE IOCTL 時,也會傳回此錯誤。

備註

SIO_SET_COMPATIBILITY_MODE IOCTL 會要求網路堆疊如何處理特定行為,而預設處理行為的方式可能會因 Windows 版本而異。 SIO_SET_COMPATIBILITY_MODE的輸入引數結構是在Mswsockdef.h標頭檔中定義的WSA_COMPATIBILITY_MODE結構中指定。 WSA_COMPATIBILITY_MODE結構的指標會傳入cbInBuffer參數。 此結構的定義如下:

// Need to #include <mswsock.h>

/* Argument structure for SIO_SET_COMPATIBILITY_MODE */
typedef struct _WSA_COMPATIBILITY_MODE {
    WSA_COMPATIBILITY_BEHAVIOR_ID BehaviorId;
    ULONG TargetOsVersion;
} WSA_COMPATIBILITY_MODE, *PWSA_COMPATIBILITY_MODE;

BehaviorId成員中指定的值表示所要求的行為。 TargetOsVersion成員中指定的值表示正在要求行為的 Windows 版本。

BehaviorId成員可以是mswsockdef.h標頭檔中所定義WSA_COMPATIBILITY_BEHAVIOR_ID列舉類型的其中一個值。 BehaviorId成員的可能值如下所示:

詞彙 描述
WsaBehaviorAll 這相當於要求針對 WSA_COMPATIBILITY_BEHAVIOR_ID定義的所有可能相容行為。
WsaBehaviorReceiveBuffering TargetOsVersion 成員設定為 Windows Vista 或更新版本的值時,即使 TCP 連線已建立之後,仍允許使用 SO_RCVBUF 通訊端選項將此通訊端上的 TCP 接收緩衝區大小縮減。 當 TargetOsVersion 成員設定為早于 Windows Vista 的值時,在連線建立之後,不允許使用 SO_RCVBUF 通訊端選項將此通訊端上的 TCP 接收緩衝區大小縮減。
WsaBehaviorAutoTuning TargetOsVersion 成員設定為 Windows Vista 或更新版本的值時,會啟用接收視窗自動調整,並將 TCP 視窗縮放比例從預設值 8 縮減為 2。 當 TargetOsVersion 設定為早于 Windows Vista 的值時,會停用接收視窗自動調整。 TCP 視窗縮放選項也會停用,而且 true 接收視窗大小上限限制為 65,535 個位元組。 即使在此通訊端上呼叫 了 SO_RCVBUF 通訊端選項,而且在建立連線之前指定大於 65,535 個位元組的值,也無法交涉連線上的 TCP 視窗調整選項。

TargetOsVersion成員可以是Sdkddkver.h標頭檔中定義的其中一個 NTDDI 版本常數。 TargetOsVersion成員的一些可能值如下:

詞彙 描述
NTDDI_LONGHORN 目標行為是 Windows Vista 的預設值。
NTDDI_WS03 目標行為是 Windows Server 2003 的預設值。
NTDDI_WINXP 目標行為是 Windows XP 的預設值。
NTDDI_WIN2K 目標行為是 Windows 2000 的預設行為。

TargetOsVersion成員的主要影響是這個成員設定為等於或大於NTDDI_LONGHORN的值。

TCP 效能不僅取決於傳輸速率本身,也取決於傳輸速率和往返延遲時間的乘積。 此頻寬延遲產品會測量「填滿管道」的資料量。 此頻寬延遲產品是傳送者和接收者所需的緩衝區空間,可透過路徑取得 TCP 連線的最大輸送量。 此緩衝區空間代表 TCP 必須處理的未套用資料量,以便讓管線保持完整狀態。 當頻寬延遲產品很大時,就會發生 TCP 效能問題。 在這些情況下運作的網路路徑通常稱為「長管線」。 範例包括高容量封包衛星連結、高速無線連結,以及長距離的光纖光學連結。

TCP 標頭使用 16 位的資料欄位 (TCP 封包標頭中的 Window 欄位,) 向傳送者報告接收視窗大小。 因此,可以使用的最大視窗是 65,535 個位元組。 為了規避這項限制,已新增 TCP 延伸模組選項 TCP 視窗縮放,以達到高效能 TCP,以允許大於 65,535 個位元組的視窗。 (WSopt) 的 TCP 視窗調整選項定義于 IETF 網站提供的 RFC 1323 中。 WSopt 延伸模組會使用一位元組對數縮放比例,將 TCP 視窗的定義擴充為 32 位,以擴充 TCP 標頭中的 16 位視窗欄位。 WSopt 延伸模組會將隱含縮放比例 (2 定義為某些電源) ,用來將 TCP 標頭中找到的視窗大小值相乘,以取得真正的視窗大小。 因此,視窗縮放比例為 8 會導致真正的視窗大小等於 TCP 標頭中 [視窗] 欄位中的值乘以 2^8 或 256。 因此,如果 TCP 標頭中的 Window 欄位設定為 65,535 個位元組的最大值,且 WSopt 縮放比例已交涉為 8 的值,則真正的視窗大小會是 16,776,960 個位元組。

真正的接收視窗大小,因此縮放比例取決於接收緩衝區空間上限。 這個最大緩衝區空間是 TCP 接收者允許 TCP 傳送者在等候認可之前傳送的資料量。 建立連線之後,接收視窗大小會在每個 TCP 區段中公告, (TCP 標頭中的 [視窗] 欄位) 。 公告傳送者可傳送的最大資料量是接收端流量控制機制,可防止傳送者傳送無法儲存的資料。 傳送主機只能在等候通知和接收視窗大小更新之前,先傳送接收者公告的資料量上限。

在 Windows Server 2003 和 Windows XP 上,表示 TCP/IP 堆疊接收視窗大小的最大接收緩衝區空間,會根據傳送介面的連結速度,提供預設值。 實際值會自動調整為在 TCP 連線建立期間交涉 (MS) S 大小上限的遞增。 因此對於 10 Mbit/sec 連結,預設接收視窗大小通常會設定為 16K 位元組,而在 100 MBit/秒連結上,預設接收視窗大小會設定為 65,535 個位元組。

在 Windows Server 2003 和 Windows XP 上,可以使用特定介面或整個系統上的下列登錄值,手動設定 TCP/IP 堆疊真正的接收視窗大小上限:

HKEY_LOCAL_MACHINE\SYSTEM\Current Control Set\Services\Tcpip\Parameters\TCPWindowSize

HKEY_LOCAL_MACHINE\SYSTEM\Current Control Set\Services\Tcpip\Parameters\Interface\TCPWindowSize

當不使用 WSopt 擴充功能時, TCPWindowSize 的登錄值可以設定為最多 65,535 個位元組,或在使用 WSopt 擴充功能時最多 1,073,741,823 個位元組, (支援最大縮放比例 4) 。 若沒有視窗調整,無論路徑頻寬為何,應用程式只能達到大約每秒 5 MB 位的輸送量, (Mbps) 路徑上的往返時間 (RTT) 。 此輸送量可以調整為每秒 1 GB (Gbps) ,這可讓 TCP 在連線建立期間交涉視窗大小的縮放比例。

在 Windows Server 2003 和 Windows XP 上,您可以藉由設定下列登錄值來啟用 WSopt 擴充功能。

HKEY_LOCAL_MACHINE\SYSTEM\Current Control Set\Services\Tcpip\Parameters\Tcp1323Opts

Tcp1323Opts登錄值是DWORD編碼,因此設定位 0 時,會啟用 TCP WSopt 擴充功能。 設定位 1 時,會啟用在 RFC 1323 中定義的 TSopt (TCP 時間戳記選項) 。 因此,1 或 3 的值會啟用 WSopt 擴充功能。

在 Windows Server 2003 和 Windows XP 上,預設值是不會建立 TCPWindowSize 和 Tcp1323Opts 登錄值。 因此,預設值是停用 WSopt 擴充功能,而且系統會根據連結速度,將 TCP 接收視窗大小設定為最多 65,535 個位元組的最大值。 當 Windows Server 2003 和 Windows XP 上啟用視窗調整時,設定 Tcp1323Opts 登錄值時,只有在傳送者和接收者同時在同步處理 (SYN) 區段中同時包含 TCP 視窗縮放選項,才能交涉視窗縮放比例。 在連線上使用視窗調整時,TCP 標頭中的 Window 欄位會設定為 65,535 個位元組,而視窗縮放比例會用來調整連線時交涉的視窗縮放比例向上調整真正的接收視窗大小。

應用程式可以使用 SO_RCVBUF 通訊端選項來指定連線的 TCP 接收視窗大小。 通訊端的 TCP 接收視窗大小可以隨時使用 SO_RCVBUF增加,但只能在建立連線之前減少。 若要使用視窗調整,應用程式必須在建立連線之前,使用 SO_RCVBUF 通訊端選項,指定大於 65,535 位元組的視窗大小。

TCP 接收視窗大小的理想值通常難以判斷。 為了填滿傳送者和接收者之間的網路容量,接收視窗大小應設定為連線的頻寬延遲產品,也就是頻寬乘以往返時間。 即使應用程式可以正確判斷頻寬延遲產品,仍然不知道接收端應用程式會從傳入資料緩衝區擷取資料的速度, (應用程式擷取速率) 。 雖然支援 TCP 視窗調整,但 Windows Server 2003 和 Windows XP 中的接收視窗 (大小上限仍可限制輸送量,因為除非每個應用程式使用 SO_RCVBUF) 指定,否則其大小上限仍會受到限制,因而可增強某些連線的輸送量,並降低其他連線的輸送量。 此外,TCP 連線的固定接收視窗大小上限不會隨著網路狀況變更而有所不同。

若要根據網路目前的狀況,正確判斷 TCP 連線接收視窗大小上限值的問題,Windows Vista 中的 TCP/IP 堆疊支援接收視窗自動調整功能。 啟用此功能時,接收視窗自動調整會持續藉由測量頻寬延遲產品和應用程式擷取速率來判斷最佳 True 接收視窗大小,並根據變更的網路狀況來調整真正的接收視窗大小上限。 接收視窗自動調整預設會啟用 TCP WSopt 擴充功能,最多允許 16,776,960 個位元組的 true 視窗大小。 當資料流程透過連線時,TCP/IP 堆疊會監視連線、測量連線和應用程式接收速率的目前頻寬延遲產品,並調整實際的接收視窗大小以優化輸送量。 TCP/IP 堆疊會根據網路條件變更 TCP 標頭中的 Window 欄位值,因為第一次建立連線時會修正 WSopt 縮放比例。

Windows Vista 中的 TCP/IP 堆疊不再使用 TCPWindowSize 登錄值。 在 TCP 對等互連之間擁有更好的輸送量時,網路頻寬的使用率會在資料傳輸期間增加。 如果所有應用程式都優化以接收 TCP 資料,則網路的整體使用率可能會大幅增加,因此使用服務品質 (QoS) 在以或接近容量運作的網路上更為重要。

未使用WsaBehaviorReceiveBuffering指定SIO_SET_COMPATIBILITY_MODE時,Windows Vista 上接收緩衝的預設行為是建立連線之後,不允許使用SO_RCVBUF通訊端選項來減少接收視窗大小。

未使用WsaBehaviorAutoTuning指定SIO_SET_COMPATIBILITY_MODE時,Windows Vista 的預設行為是堆疊會使用視窗縮放比例 8 接收視窗自動調整。 請注意,如果應用程式使用 [SO_RCVBUF 通訊端] 選項設定有效的接收視窗大小,堆疊將會使用指定的大小,而視窗接收自動調整將會停用。 Windows 自動調整也可以使用下列命令完全停用, netsh interface tcp set global autotuninglevel=disabled 在此情況下,指定 WsaBehaviorAutoTuning 將不會有任何影響。 您也可以根據 Windows Server 2008 上設定的群組原則停用視窗接收自動調整。

Windows Vista 上需要 WsaBehaviorAutoTuning 選項,某些網際網路閘道裝置和防火牆無法正確支援使用 WSopt 擴充功能和 Windows 縮放比例的 TCP 連線資料流程。 在 Windows Vista 上,接收者預設會交涉視窗縮放比例 8,以取得最大 true 視窗大小 16,776,960 個位元組。 當資料開始在快速連結上流動時,Windows 一開始會藉由將 TCP 標頭的 Window 欄位設定為 256,並將 TCP 選項中的視窗縮放比例設定為 8, (256*2^8=64KB) 開始。 某些網際網路閘道裝置和防火牆會忽略視窗縮放比例,並只查看指定為 256 之 TCP 標頭中的公告視窗欄位,並針對包含超過 256 個 TCP 資料的連線卸載傳入封包。 若要支援 TCP 接收視窗調整,閘道裝置或防火牆必須監視 TCP 交握,並在 TCP 連線資料中追蹤交涉的視窗縮放比例。 此外,其他平臺上的某些應用程式和 TCP 堆疊實作會忽略 TCP WSopt 擴充功能和視窗縮放比例。 因此,傳送資料的遠端主機可能會以 TCP 標頭的 Window 欄位中公告的速率傳送資料, (256 個位元組) 。 這可能會導致接收者非常慢地接收資料。

BehaviorId 成員設定為 WsaBehaviorAutoTuning ,並將 TargetOsVersion 設定為 Windows Vista 會將視窗縮放比例減少為 2,因此 TCP 標頭中的 Window 欄位一開始會設定為 16,384 個位元組,而視窗縮放比例會設定為 2,以取得初始 true 視窗接收大小為 64K 位元組。 然後,視窗自動調整功能可以將 TCP 標頭中的 Window 欄位設定為 65,535 個位元組,以增加最多 262,140 個位元組的視窗接收大小。 應用程式在建立通訊端時應該設定 SIO_SET_COMPATIBILITY_MODE IOCTL,因為此選項在傳送 SYN 之後並無意義或套用。 設定此選項的影響與下列命令相同: netsh interface tcp set global autotuninglevel=highlyrestricted

請注意, Mswsockdef.h 標頭檔會自動包含在 Mswsock.hNetiodef.h中,不應直接使用。

另請參閱

socket

WSAGetLastError

WSAGetOverlappedResult

WSAIoctl

WSAOVERLAPPED

WSASocketA

WSASocketW