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 套接字 1.1 调用正在进行,或者服务提供商仍在处理回调函数。 | |
级别参数未知或无效。 | |
选项未知或不受所指示的协议系列支持。 | |
:描述符不是套接字。 |
注解
getsockopt 函数检索与任何类型、处于任何状态的套接字关联的套接字选项的当前值,并将结果存储在 optval 中。 选项可以存在于多个协议级别,但它们始终存在于最上面的套接字级别。 选项会影响套接字操作,例如数据包路由和 OOB 数据传输。
与所选选项关联的值在缓冲区 optval 中返回。 optlen 指向的整数最初应包含此缓冲区的大小;返回时,它将设置为返回的值的大小。 对于SO_LINGER,这是 LINGER 结构的大小。 对于大多数其他选项,它将是整数的大小。
应用程序负责分配由它指定的任何参数直接或间接指向的任何内存空间。
如果从未使用 setockopt 设置选项,则 getsockopt 返回选项的默认值。
getsockopt 支持以下选项。 “类型”列标识 optval 寻址的数据类型。
有关套接字选项的详细信息,请参阅 套接字选项。
当 level 参数设置为 SOL_SOCKET 时,optname 参数的值表有效。
值 | 类型 | 含义 |
---|---|---|
SO_ACCEPTCONN | BOOL | 套接字正在侦听。 |
SO_BROADCAST | BOOL | 套接字配置为用于传输和接收广播消息。 |
SO_BSP_STATE | CSADDR_INFO | 返回套接字使用的本地地址、本地端口、远程地址、远程端口、套接字类型和协议。 |
SO_CONDITIONAL_ACCEPT | BOOL | 从上一次调用 setsockopt 或系统默认值返回当前套接字状态。 |
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 | 阻止任何其他套接字绑定到同一地址和端口。 在调用 绑定 函数之前,必须设置此选项。 |
SO_GROUP_ID | GROUP | 保留。 |
SO_GROUP_PRIORITY | int | 保留。 |
SO_KEEPALIVE | BOOL | 正在发送“保持连接”。 ATM 套接字不支持。 |
SO_LINGER | LINGER 结构 | 返回当前的逗留选项。 |
SO_MAX_MSG_SIZE | unsigned int | 面向消息的套接字类型的消息的最大大小 (例如,SOCK_DGRAM) 。 对于面向流的套接字没有意义。 |
SO_OOBINLINE | BOOL | 正在正常数据流中接收 OOB 数据。 (有关本主题的讨论,请参阅 Windows 套接字 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 和更新版本中受支持。 |
下表列出了表示 getsockopt 函数不支持的 BSD 套接字选项的 optname 的值。
值 | 类型 | 含义 |
---|---|---|
SO_RCVLOWAT | int | 接收低水印。 |
SO_RCVTIMEO | int | 接收超时。 |
SO_SNDLOWAT | int | 发送低水印。 |
SO_SNDTIMEO | int | 发送超时。 |
TCP_MAXSEG | int | 接收 TCP 最大段大小。 在Windows 10之前的版本中不受支持。 |
使用不支持的选项调用 getockopt 将导致从 WSAGetLastError 返回 WSAENOPROTOOPT 的错误代码。
下面列出了有关 getsockopt 函数支持的 optname 参数的一些套接字选项的详细信息。
- SO_CONNECT_TIME
-
此选项返回已连接套接字的秒数。 此选项仅适用于面向连接的协议。
SO_CONNECT_TIME 选项可与 getsockopt 函数一起使用,以检查是否已建立连接。 当 ConnectEx 函数调用正在进行时,也可以使用此选项。 如果已建立连接,SO_CONNECT_TIME选项可以确定建立连接的时间。 如果未连接套接字, 则 getsockopt 返回SOCKET_ERROR。 需要检查这样的连接,以查看是否已建立一段时间的连接,而无需发送任何数据。 建议应用程序终止这些连接。
- SO_DEBUG
-
注意 如果应用程序设置了SO_DEBUG选项,则建议 Windows 套接字服务提供商 (但不要求) 提供输出调试信息。 生成调试信息的机制及其采用的形式超出了本文档的范围。
- SO_ERROR
- SO_ERROR 选项返回并重置每个套接字的错误代码,这与使用 WSAGetLastError 和 WSASetLastError 函数调用处理的基于线程的错误代码不同。 使用套接字的成功调用不会重置 SO_ERROR 选项返回的基于套接字的错误代码。
- SO_EXCLUSIVEADDRUSE
- 阻止任何其他套接字绑定到同一地址和端口。 在调用 绑定 函数之前,必须设置此选项。 有关详细信息,请参阅 SO_EXCLUSIVEADDRUSE 参考。
- SO_GROUP_ID
-
注意 此选项是保留的。 此选项也是 getsockopt 独有的;值应为 NULL。
- SO_GROUP_PRIORITY
-
此选项是保留的。 组优先级指示指定套接字相对于套接字组内其他套接字的优先级。 值是非否定整数,零对应于最高优先级。 优先级值表示基础服务提供商关于应如何分配潜在稀缺资源的提示。 例如,每当两个或更多个套接字都准备好传输数据时,应首先为SO_GROUP_PRIORITY) 的最高优先级套接字 (最低值提供服务,其余套接字根据其相对优先级依次提供服务。
对于非组套接字或不支持组套接字的服务提供程序,指示 WSAENOPROTOOPT 错误代码。
- SO_KEEPALIVE
- 应用程序可以通过打开“SO_KEEPALIVE套接字”选项,请求 TCP/IP 服务提供商允许在 TCP 连接上使用保持连接数据包。 此选项查询套接字上 keep-alive 选项的当前值。 Windows 套接字提供程序不需要支持使用 keep-alive:如果支持,则精确的语义是特定于实现的,但应符合 IETF 网站上 RFC 1122 中指定的 Internet 主机要求 (RFC 1122 中指定的通信层)中的 4.2.3.6 部分。 如果由于保持连接而断开连接,则错误代码 WSAENETRESET 将返回到套接字上正在进行的任何调用,并且任何后续调用都将失败, WSAENOTCONN。 SO_KEEPALIVE 在 ATM 套接字上不受支持,并且请求在 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 套接字实现支持SO_RCVBUF和SO_SNDBUF选项时,应用程序可以请求不同的缓冲区大小 (更大或更小) 。 即使实现未提供请求的全部数量,对 setsockopt 的调用也会成功。 应用程序必须使用相同的选项调用此函数,以检查实际提供的缓冲区大小。
- SO_REUSEADDR
- 默认情况下,无法绑定套接字, (看到 绑定到 已使用的本地地址) 。 但是,有时可能需要以这种方式重用地址。 由于每个连接都是由本地地址和远程地址组合唯一标识的,因此,只要远程地址不同,将两个套接字绑定到同一本地地址就没有问题。 若要通知 Windows 套接字提供程序不应禁止某个套接字上的 绑定 ,因为所需的地址已被另一个套接字使用,应用程序应在发出 绑定之前为套接字设置SO_REUSEADDR套接字选项。 请注意,选项仅在 绑定时被解释:因此,在不绑定到现有地址的套接字上设置选项是不必要的 (但无害的) ,并在 绑定 后设置或重置选项对此或任何其他套接字没有影响。 SO_REUSEADDR不适用于 ATM 套接字,尽管重复使用和地址的请求不会导致错误,但它们对使用 ATM 套接字时没有影响。
- PVD_CONFIG
- 此选项从 与套接字关联的服务提供程序检索不透明的数据结构对象。 此对象存储服务提供程序的当前配置信息。 此数据结构的确切格式特定于服务提供商。
- TCP_NODELAY
- TCP_NODELAY选项特定于 TCP/IP 服务提供商。 如果启用TCP_NODELAY选项 (,则禁用 Nagle 算法,反之亦然) 。 RFC 896) 中所述的 Nagle 算法 (在减少主机发送的小数据包数量方面非常有效。 此过程涉及在尚未确认的数据处于未确认状态时缓冲发送数据,或缓冲发送数据,直到可以发送完整大小的数据包。 强烈建议 Windows 套接字实现默认启用 Nagle 算法,因为对于绝大多数应用程序协议,Nagle 算法可以提供显著的性能增强。 但是,对于某些应用程序,此算法可能会降低性能,并且可以使用具有相同选项的 setsockopt 将其关闭。 这些应用程序发送了许多小消息,并维护消息之间的时间延迟。
示例代码
以下代码示例演示如何使用 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 套接字连接之前,必须通过执行 getsockopt (,IRLMP_ENUMDEVICES,) 函数调用来获取设备地址,这会返回所有可用的 IrDA 设备的列表。 从函数调用返回的设备地址将复制到 SOCKADDR_IRDA 结构中,后者又由 对 connect 函数调用的后续调用使用。
可以通过两种方式执行发现:
-
首先,使用 IRLMP_ENUMDEVICES 选项执行 getsockopt 函数调用会导致在每个空闲适配器上运行单个发现。 ) 活动适配器上 (已发现设备和缓存设备的列表会立即返回。
以下代码演示了此方法。
#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 数据库中检索单个类的单个属性。 应用程序指定要查询的设备和类以及属性和属性类型。 请注意,设备之前是通过调用 getsockopt (IRLMP_ENUMDEVICES) 获取的。 预期应用程序会为返回的参数分配一个具有所需大小的缓冲区。
许多级别套接字选项对 IrDA 没有意义;仅专门支持SO_LINGER和SO_DONTLINGER。
Windows Phone 8:Windows Phone 8 及更高版本上的 Windows Phone 应用商店应用支持此函数。
Windows 8.1和Windows Server 2012 R2:Windows 8.1、Windows Server 2012 R2 及更高版本的 Windows 应用商店应用支持此函数。
要求
要求 | 值 |
---|---|
最低受支持的客户端 | Windows 8.1,Windows Vista [桌面应用 |UWP 应用] |
最低受支持的服务器 | Windows Server 2003 [桌面应用 | UWP 应用] |
目标平台 | Windows |
标头 | winsock.h (包括 Winsock2.h) |
Library | Ws2_32.lib |
DLL | Ws2_32.dll |