getsockopt 函式 (winsock.h)
getsockopt 函式會擷取套接字選項。
語法
int getsockopt(
[in] SOCKET s,
[in] int level,
[in] int optname,
[out] char *optval,
[in, out] int *optlen
);
參數
[in] s
識別套接字的描述項。
[in] level
定義選項的層級。 範例: SOL_SOCKET。
[in] optname
要擷取值的套接字選項。 範例: SO_ACCEPTCONN。 optname 值必須是指定層級內定義的套接字選項,或未定義行為。
[out] optval
要傳回所要求選項值的緩衝區指標。
[in, out] optlen
optval 緩衝區的大小指標,以位元組為單位。
傳回值
如果沒有發生錯誤, 則 getsockopt 會傳回零。 否則,會傳回SOCKET_ERROR的值,並呼叫 WSAGetLastError 來擷取特定的錯誤碼。
錯誤碼 | 意義 |
---|---|
使用這個函式之前,必須先進行成功的 WSAStartup 呼叫。 | |
注意 網路子系統失敗。
|
|
其中一個 optval 或 optlen 參數不是使用者地址空間的有效部分,或 optlen 參數太小。 | |
封鎖的 Windows Sockets 1.1 呼叫正在進行中,或服務提供者仍在處理回呼函式。 | |
level 參數未知或無效。 | |
指定的通訊協定系列未知或不支援此選項。 | |
描述項不是套接字。 |
備註
getsockopt 函式會擷取與任何類型套接字、處於任何狀態的套接字選項相關聯的目前值,並將結果儲存為 optval。 選項可以存在於多個通訊協定層級,但它們一律存在於最上層的套接字層級。 選項會影響套接字作業,例如封包路由和 OOB 數據傳輸。
與所選取選項相關聯的值會在緩衝區 選擇值中傳回。 optlen 所指向的整數應該原本包含這個緩衝區的大小;在傳回時,它會設定為傳回之值的大小。 對於SO_LINGER,這會是 LINGER 結構的大小。 對於大部分的其他選項,它會是整數的大小。
應用程式負責配置它所指定任何參數直接或間接指向的任何記憶體空間。
如果從未使用 setsockopt 設定選項, 則 getsockopt 會傳回選項的預設值。
取得ockopt 支援下列選項。 Type 資料行會識別 optval 所尋址的數據類型。
如需套接字選項的詳細資訊,請參閱 套接字選項。
當 level 參數設定為 SOL_SOCKET 時,optname 參數的下表有效。
值 | 類型 | 意義 |
---|---|---|
SO_ACCEPTCONN | BOOL | 通訊端正在接聽。 |
SO_BROADCAST | BOOL | 套接字會針對廣播訊息的傳輸和接收進行設定。 |
SO_BSP_STATE | CSADDR_INFO | 傳回套接字所使用的本機位址、本機埠、遠端位址、遠端埠、套接字類型和通訊協定。 |
SO_CONDITIONAL_ACCEPT | BOOL | 從先前呼叫 setockopt 或系統預設值傳回目前的套接字狀態。 |
SO_CONNECT_TIME | DWORD | 傳回套接字已連接的秒數。 此套接字選項僅適用於連線導向通訊協定。 |
SO_DEBUG | BOOL | 已啟用偵錯。 |
SO_DONTLINGER | BOOL | 如果 為 TRUE,則會停用 [SO_LINGER] 選項。 |
SO_DONTROUTE | BOOL | 路由已停用。 設定此動作成功,但在AF_INET套接字上會被忽略;在具有 WSAENOPROTOOPT 的AF_INET6套接字上失敗。 ATM 套接字不支援此選項。 |
SO_ERROR | int | 擷取錯誤狀態並清除。 |
SO_EXCLUSIVEADDRUSE | BOOL | 防止任何其他套接字系結至相同的位址和埠。 呼叫 bind 函式之前,必須先設定這個選項。 |
SO_GROUP_ID | GROUP | 保留的。 |
SO_GROUP_PRIORITY | int | 保留的。 |
SO_KEEPALIVE | BOOL | 正在傳送 Keep-alives。 ATM 套接字不支援。 |
SO_LINGER | LINGER 結構 | 傳回目前的linger 選項。 |
SO_MAX_MSG_SIZE | 不帶正負號的整數 | 訊息導向套接字類型的訊息大小上限 (例如,SOCK_DGRAM) 。 對數據流導向套接字沒有任何意義。 |
SO_OOBINLINE | BOOL | OOB 數據正在一般數據流中接收。 (如需本主題的討論,請參閱 Windows Sockets 1.1 封鎖例程和 EINPROGRESS 一節。) |
SO_PORT_SCALABILITY | BOOL | 藉由在本機計算機上為不同本機位址埠組配置通配符埠多次,讓埠配置最大化,以啟用套接字的本機埠延展性。 |
SO_PROTOCOL_INFO | WSAPROTOCOL_INFO | 系結至此套接字之通訊協議的通訊協議資訊描述。 |
SO_RCVBUF | int | 保留給接收的個別套接字緩衝區空間總計。 這與SO_MAX_MSG_SIZE無關,而且不一定對應至 TCP 接收視窗的大小。 |
SO_REUSEADDR | BOOL | 套接字可以系結至已在使用的位址。 不適用於 ATM 套接字。 |
SO_SNDBUF | int | 保留給傳送的每個套接字緩衝區空間總計。 這與SO_MAX_MSG_SIZE無關,而且不一定對應至 TCP 傳送視窗的大小。 |
SO_TYPE | int | 例如,套接字 (的類型,SOCK_STREAM) 。 |
PVD_CONFIG | 服務提供者相依 | 與 套接字相關聯之服務提供者的不透明數據結構物件。 此物件會儲存服務提供者的目前組態資訊。 此數據結構的確切格式是服務提供者的特定格式。 |
水準 = IPPROTO_TCP
請參閱IPPROTO_TCP套接字選項中的TCP_NODELAY。 另請參閱該主題,以取得 層級 = IPPROTO_TCP之套接字選項的更完整和詳細資訊。
當 level 參數設定為 NSPROTO_IPX 時,optname 參數的下表有效。
- IPX_PTYPE
- IPX_FILTERPTYPE
- IPX_DSTYPE
- IPX_RECVHDR
- IPX_MAXSIZE
- IPX_ADDRESS
值 | 類型 | 意義 |
---|---|---|
IPX_PTYPE | int | 擷取IPX封包類型。 |
IPX_FILTERPTYPE | int | 擷取接收篩選封包類型 |
IPX_DSTYPE | int | 取得每個已傳送封包之SPX標頭中數據流欄位的值。 |
IPX_EXTENDED_ADDRESS | BOOL | 瞭解是否啟用擴充尋址。 |
IPX_RECVHDR | BOOL | 找出是否在所有接收標頭上傳送通訊協議標頭。 |
IPX_MAXSIZE | int | 取得可傳送的數據大小上限。 |
IPX_ADDRESS | IPX_ADDRESS_DATA 結構 | 取得IPX所系結之特定配接器的相關信息。 配接器編號為基底零。 傳回時會填入 adapternum 成員。 |
IPX_GETNETINFO | IPX_NETNUM_DATA 結構 | 取得特定IPX網路號碼的相關信息。 如果快取中無法使用,請使用 RIP 來取得資訊。 |
IPX_GETNETINFO_NORIP | IPX_NETNUM_DATA 結構 | 取得特定IPX網路號碼的相關信息。 如果快取中無法使用,將不會使用 RIP 來取得資訊,並傳回錯誤。 |
IPX_SPXGETCONNECTIONSTATUS | IPX_SPXCONNSTATUS_DATA 結構 | 擷取連線 SPX 套接字的相關信息。 |
IPX_ADDRESS_NOTIFY | IPX_ADDRESS_DATA 結構 | 當IPX系結的適配卡發生變更時,擷取狀態通知。 |
IPX_MAX_ADAPTER_NUM | int | 擷取存在的配接器數目上限,編號為基底零。 |
IPX_RERIPNETNUMBER | IPX_NETNUM_DATA 結構 | 類似於 IPX_GETNETINFO,但即使網路資訊位於本機快取中,仍會強制IPX使用 RIP 進行解析。 |
IPX_IMMEDIATESPXACK | BOOL | 指示SPX連線在傳送 ACK 之前不會延遲。 沒有來回流量的應用程式應該將此設定為 TRUE ,以提升效能。 |
TCP_MAXSEG | int | 接收 TCP 最大區段大小。 Windows 10 和更新版本支援。 |
下表列出 optname 的值,代表 取得ockopt 函式不支援的 BSD 套接字選項。
值 | 類型 | 意義 |
---|---|---|
SO_RCVLOWAT | int | 接收低水位線。 |
SO_RCVTIMEO | int | 接收逾時。 |
SO_SNDLOWAT | int | 傳送低水位線。 |
SO_SNDTIMEO | int | 傳送逾時。 |
TCP_MAXSEG | int | 接收 TCP 最大區段大小。 Windows 10 之前的版本不支援。 |
使用不支持的選項呼叫 getockopt 會導致從 WSAGetLastError 傳回 WSAENOPROTOOPT 的錯誤碼。
以下列出有關取得ockopt 函式所支援之 optname 參數之部分套接字選項的詳細資訊。
- SO_CONNECT_TIME
-
此選項會傳回套接字已連接的秒數。 此選項僅適用於連線導向通訊協定。
SO_CONNECT_TIME選項可以搭配 取得ockopt 函式使用,以檢查是否已建立連線。 當 ConnectEx 函數調用正在進行時,也可以使用此選項。 如果已建立連線,則SO_CONNECT_TIME選項可以決定連線的建立時間長度。 如果套接字未連線, 則 getsockopt 會傳回SOCKET_ERROR。 檢查這類連線是必要的,才能查看是否已建立一段時間的連線,而不傳送任何數據。 建議應用程式終止這些連線。
- SO_DEBUG
-
注意 如果應用程式設定了SO_DEBUG選項,則建議使用 Windows Sockets 服務提供者 (,但不需要) 提供輸出偵錯資訊。 產生偵錯資訊和表單的機制超出本檔的範圍。
- SO_ERROR
- SO_ERROR選項會傳回並重設每個套接字型錯誤碼,這與使用 WSAGetLastError 和 WSASetLastError 函數呼叫所處理的每個線程型錯誤碼不同。 使用套接字的成功呼叫不會重設 SO_ERROR 選項所傳回的套接字錯誤碼。
- SO_EXCLUSIVEADDRUSE
- 防止任何其他套接字系結至相同的位址和埠。 呼叫 系結 函式之前,必須先設定這個選項。 如需詳細資訊 ,請參閱SO_EXCLUSIVEADDRUSE 參考。
- SO_GROUP_ID
-
注意 此選項是保留的。 此選項也適用於 取得ockopt;此值應該是 NULL。
- SO_GROUP_PRIORITY
-
此選項是保留的。 群組優先順序表示指定套接字相對於套接字群組內其他套接字的優先順序。 值是非負整數,且零對應於最高優先順序。 優先順序值代表基礎服務提供者的提示,說明應該如何配置潛在的資源。 例如,每當兩個以上的套接字都準備好傳輸數據時,應該先針對SO_GROUP_PRIORITY) 提供最高优先级的套接字 (最低值,然後根據相對優先順序來服務其餘部分。
針對非群組套接字或不支援群組套接字的服務提供者,會指出 WSAENOPROTOOPT 錯誤碼。
- SO_KEEPALIVE
- 應用程式可以藉由開啟 [SO_KEEPALIVE套接字] 選項,要求 TCP/IP 服務提供者能夠使用 TCP 連線上的保持連線封包。 此選項會查詢套接字上keep-alive選項的目前值。 Windows Sockets 提供者不需要支援使用keep-alive:如果是,精確語意是特定實作,但應該符合 IETF 網站上 RFC 1122 中指定的通訊層第 4.2.3.6 節。 如果連線因為保持運作而中斷,則會將錯誤碼 WSAENETRESET 傳回至套接字上進行的任何呼叫,而任何後續的呼叫都會因為 WSAENOTCONN 而失敗。 ATM 套接字不支援SO_KEEPALIVE,而且在 ATM 套接字上啟用保持運作封包的要求會導致套接字傳回錯誤。
- SO_LINGER
- SO_LINGER控制在套接字上排入未傳送數據並執行 closesocket 時所採取的動作。 如需SO_LINGER設定會影響 closesocket 語意的方式描述,請參閱 closesocket。 應用程式會擷取 optval 參數所指向的 LINGER 結構 (,以取得目前的行為) 。
- SO_MAX_MSG_SIZE
- 這是僅限取得的套接字選項,表示訊息導向套接字類型 ( (輸出) 大小上限,例如,SOCK_DGRAM) 由特定服务提供商实作。 它對位元組數據流導向套接字沒有意義。 沒有布建可找出輸入訊息大小上限。
- SO_PROTOCOL_INFO
- 這是唯一選項,可提供與此套接字相關聯的 WSAPROTOCOL_INFO 結構。 如需此結構的詳細資訊,請參閱 WSAEnumProtocols 。
- SO_SNDBUF
- 當 Windows Sockets 實作支援SO_RCVBUF和SO_SNDBUF選項時,應用程式可以要求不同的緩衝區大小, (較大或較小的) 。 即使實作未提供所要求的整個數量, setockopt 的呼叫仍可成功。 應用程式必須使用相同的選項呼叫此函式,才能檢查實際提供的緩衝區大小。
- SO_REUSEADDR
- 根據預設,套接字無法系結 (請參閱系 結) 已使用中的本機位址。 不過,有時候,可能需要以這種方式重複使用位址。 由於每個連線都是由本機和遠端位址的組合所唯一識別,因此只要遠端位址不同,兩個套接字系結至相同的本機位址就沒有任何問題。 若要通知 Windows Sockets 提供者,因為所需的位址已由另一個套接字使用中,所以不應該允許套接字上的 系 結,應用程式應該先設定套接字的 SO_REUSEADDR 套接字選項,再發出 系結。 請注意,只有在系 結時才會解譯選項:因此不必要 (但無損害的) ,在不繫結至現有位址的套接字上設定選項,並在系 結 之後設定或重設選項不會影響這個或任何其他套接字。 SO_REUSEADDR不適用於 ATM 套接字,雖然重複使用和位址的要求不會造成錯誤,但是當 ATM 套接字正在使用時,它們不會有任何作用。
- PVD_CONFIG
- 此選項會從 與套接字相關聯的服務提供者擷取不透明的數據結構物件。 此物件會儲存服務提供者的目前組態資訊。 此數據結構的確切格式是服務提供者的特定格式。
- TCP_NODELAY
- TCP_NODELAY選項是 TCP/IP 服務提供者特有的選項。 如果啟用 TCP_NODELAY 選項,則會停用 Nagle 演算法 (,反之亦然) 。 RFC 896) 中所述的 Nagle 演演算法 (在減少主機所傳送的小型封包數目方面非常有效。 此程式牽涉到在正式發行前小眾測試版或緩衝傳送數據時緩衝傳送數據,直到可以傳送完整大小的封包為止。 強烈建議 Windows Sockets 實作預設啟用 Nagle 演算法,因為針對大部分的應用程式通訊協定,Nagle 演算法可以提供顯著的效能增強功能。 不過,對於某些應用程式,此演算法可能會阻礙效能,而且可以使用相同選項的 setockopt 將其關閉。 這些是傳送許多小型訊息的應用程式,以及維護訊息之間的時間延遲。
範例程序代碼
下列程式代碼範例示範如何使用 getsockopt 函式。#include <stdio.h>
#include "winsock2.h"
#include <windows.h>
void main() {
//---------------------------------------
// Declare variables
WSADATA wsaData;
SOCKET ListenSocket;
sockaddr_in service;
//---------------------------------------
// Initialize Winsock
int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
if( iResult != NO_ERROR )
printf("Error at WSAStartup\n");
//---------------------------------------
// Create a listening socket
ListenSocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if (ListenSocket == INVALID_SOCKET) {
printf("Error at socket()\n");
WSACleanup();
return;
}
//---------------------------------------
// Bind the socket to the local IP address
// and port 27015
hostent* thisHost;
char* ip;
u_short port;
port = 27015;
thisHost = gethostbyname("");
ip = inet_ntoa (*(struct in_addr *)*thisHost->h_addr_list);
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr(ip);
service.sin_port = htons(port);
if ( bind( ListenSocket,(SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR ) {
printf("bind failed\n");
closesocket(ListenSocket);
return;
}
//---------------------------------------
// Initialize variables and call getsockopt.
// The SO_ACCEPTCONN parameter is a socket option
// that tells the function to check whether the
// socket has been put in listening mode or not.
// The various socket options return different
// information about the socket. This call should
// return 0 to the optVal parameter, since the socket
// is not in listening mode.
int optVal;
int optLen = sizeof(int);
if (getsockopt(ListenSocket,
SOL_SOCKET,
SO_ACCEPTCONN,
(char*)&optVal,
&optLen) != SOCKET_ERROR)
printf("SockOpt Value: %ld\n", optVal);
//---------------------------------------
// Put the listening socket in listening mode.
if (listen( ListenSocket, 100 ) == SOCKET_ERROR) {
printf("error listening\n");
}
//---------------------------------------
// Call getsockopt again to verify that
// the socket is in listening mode.
if (getsockopt(ListenSocket,
SOL_SOCKET,
SO_ACCEPTCONN,
(char*)&optVal,
&optLen) != SOCKET_ERROR)
printf("SockOpt Value: %ld\n", optVal);
WSACleanup();
return;
}
IrDA 套接字注意事項
- 必須明確包含 Af_irda.h 頭檔。
- Windows 會傳回 WSAENETDOWN ,以指出基礎無線電驅動程式無法使用 IrDA 通訊協定堆疊初始化。
- IrDA 支援數個特殊套接字選項:
值 類型 意義 IRLMP_ENUMDEVICES *DEVICELIST 描述範圍中的裝置。 IRLMP_IAS_QUERY *IAS_QUERY 擷取 IAS 屬性。
在可以起始 IrDA 套接字連線之前,必須執行取得裝置位址,方法是執行 取得取得的取得 (,IRLMP_ENUMDEVICES ,) 函式呼叫,這會傳回所有可用的 IrDA 裝置清單。 從函數調用傳回的裝置位址會複製到 SOCKADDR_IRDA 結構中,接著會由 連接 函數調用的後續呼叫使用。
探索可以透過兩種方式執行:
-
首先,使用 IRLMP_ENUMDEVICES 選項執行取得ockopt 函式呼叫,會導致每個閑置配接器上執行單一探索。 系統會立即傳回作用中適配卡上 (探索到的裝置和快取裝置清單) 。
下列程式代碼示範此方法。
#include <winsock2.h> #include <ws2tcpip.h> #include <af_irda.h> #include <stdio.h> #include <windows.h> // link with Ws2_32.lib int __cdecl main() { //----------------------------------------- // Declare and initialize variables WSADATA wsaData; int iResult; int i; DWORD dwError; SOCKET Sock = INVALID_SOCKET; #define DEVICE_LIST_LEN 10 SOCKADDR_IRDA DestSockAddr = { AF_IRDA, 0, 0, 0, 0, "SampleIrDAService" }; unsigned char DevListBuff[sizeof (DEVICELIST) - sizeof (IRDA_DEVICE_INFO) + (sizeof (IRDA_DEVICE_INFO) * DEVICE_LIST_LEN)]; int DevListLen = sizeof (DevListBuff); PDEVICELIST pDevList; pDevList = (PDEVICELIST) & DevListBuff; // Initialize Winsock iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if (iResult != 0) { printf("WSAStartup failed: %d\n", iResult); return 1; } Sock = socket(AF_IRDA, SOCK_STREAM, 0); if (Sock == INVALID_SOCKET) { dwError = WSAGetLastError(); printf ("socket failed trying to create an AF_IRDA socket with error %d\n", dwError); if (dwError == WSAEAFNOSUPPORT) { printf("Check that the local computer has an infrared device\n"); printf ("and a device driver is installed for the infrared device\n"); } WSACleanup(); return 1; } // Sock is not in connected state iResult = getsockopt(Sock, SOL_IRLMP, IRLMP_ENUMDEVICES, (char *) pDevList, &DevListLen); if (iResult == SOCKET_ERROR) { printf("getsockopt failed with error %d\n", WSAGetLastError()); WSACleanup(); return 1; } if (pDevList->numDevice == 0) { // no devices discovered or cached // not a bad idea to run a couple of times printf("No IRDA devices were discovered or cached\n"); } else { // one per discovered device for (i = 0; i < (int) pDevList->numDevice; i++) { // typedef struct _IRDA_DEVICE_INFO // { // u_char irdaDeviceID[4]; // char irdaDeviceName[22]; // u_char irdaDeviceHints1; // u_char irdaDeviceHints2; // u_char irdaCharSet; // } _IRDA_DEVICE_INFO; // pDevList->Device[i]. see _IRDA_DEVICE_INFO for fields // display the device names and let the user select one } } // assume the user selected the first device [0] memcpy(&DestSockAddr.irdaDeviceID[0], &pDevList->Device[0].irdaDeviceID[0], 4); iResult = connect(Sock, (const struct sockaddr *) &DestSockAddr, sizeof (SOCKADDR_IRDA)); if (iResult == SOCKET_ERROR) { printf("connect failed with error %d\n", WSAGetLastError()); } else printf("connect to first IRDA device was successful\n"); WSACleanup(); return 0; }
- 執行 IrDA 裝置位址探索的第二種方法是執行延遲探索;在此方法中,在探索到的裝置列出堆疊執行的最後一個探索變更之前,應用程式不會收到通知。
上表中 [類型] 資料行中顯示的 IAS_QUERY 結構可用來從對等裝置的 IAS 資料庫擷取單一類別的單一屬性。 應用程式會指定要查詢的裝置和類別,以及屬性和屬性類型。 請注意,裝置先前會透過 呼叫取得取得ockopt (IRLMP_ENUMDEVICES) 。 應用程式預期會為傳回的參數配置必要大小的緩衝區。
許多層級套接字選項對 IrDA 沒有意義;僅支援SO_LINGER和SO_DONTLINGER。
Windows Phone 8:Windows Phone 8 和更新版本上的 Windows Phone Store 應用程式支援此函式。
Windows 8.1 和 Windows Server 2012 R2:Windows 市集應用程式支援此函式,Windows 8.1、Windows Server 2012 R2 及更新版本。
規格需求
需求 | 值 |
---|---|
最低支援的用戶端 | Windows 8.1、Windows Vista [傳統型應用程式 |UWP 應用程式] |
最低支援的伺服器 | Windows Server 2003 [傳統型應用程式 |UWP 應用程式] |
目標平台 | Windows |
標頭 | winsock.h (包含 Winsock2.h) |
程式庫 | Ws2_32.lib |
Dll | Ws2_32.dll |