setsockopt 函数 (winsock.h)

setsockopt 函数设置套接字选项。

语法

int setsockopt(
  [in] SOCKET     s,
  [in] int        level,
  [in] int        optname,
  [in] const char *optval,
  [in] int        optlen
);

参数

[in] s

标识套接字的描述符。

[in] level

选项定义的级别 (例如,SOL_SOCKET) 。

[in] optname

要为其设置值的套接字选项 (,例如,SO_BROADCAST) 。 optname 参数必须是在指定级别内定义的套接字选项,或者行为未定义。

[in] optval

指向在其中指定所请求选项值的缓冲区的指针。

[in] optlen

optval 参数指向的缓冲区的大小(以字节为单位)。

返回值

如果未发生错误, 则 setsockopt 返回零。 否则,将返回SOCKET_ERROR值,并且可以通过调用 WSAGetLastError 来检索特定的错误代码。

错误代码 含义
WSANOTINITIALISED
在使用此函数之前,必须执行成功的 WSAStartup 调用。
WSAENETDOWN
网络子系统失败。
WSAEFAULT
optval 参数指向的缓冲区不在进程地址空间的有效部分,或者 optlen 参数太小。
WSAEINPROGRESS
正在执行阻止的 Windows 套接字 1.1 调用,或者服务提供商仍在处理回调函数。
WSAEINVAL
级别参数无效,或者 optval 参数指向的缓冲区中的信息无效。
WSAENETRESET
设置SO_KEEPALIVE时,连接已超时。
WSAENOPROTOOPT
指定提供程序或套接字 (选项未知或不受支持,请参阅) SO_GROUP_PRIORITY限制。
WSAENOTCONN
设置SO_KEEPALIVE时,连接已重置。
WSAENOTSOCK
:描述符不是套接字。

注解

setsockopt 函数设置与任何状态的套接字关联的套接字选项的当前值。 尽管选项可以存在于多个协议级别,但它们始终存在于最顶层的套接字级别。 选项会影响套接字操作,例如是否在正常数据流中接收) 的加速数据 (OOB 数据,以及是否可以在套接字上发送广播消息。

注意如果在绑定函数之前调用 setsockopt 函数,则在绑定发生之前,不会使用 TCP/IP 检查 TCP/IP 选项。 在这种情况下,setsockopt 函数调用将始终成功,但由于早期 setsockopt 调用失败,绑定函数调用可能会失败。
 
注意 如果打开套接字,将进行 setsockopt 调用,然后发出 sendto 调用,Windows 套接字将执行隐式 绑定 函数调用。
 
有两种类型的套接字选项:启用或禁用功能或行为的布尔选项,以及需要整数值或结构的选项。 若要启用布尔选项, optval 参数指向非零整数。 禁用选项 optval 指向等于零的整数。 optlen 参数应等于sizeof(int)布尔选项。 对于其他选项, optval 指向包含选项所需值的整数或结构, optlen 是整数或结构的长度。

下表列出了 setsockopt 函数支持的一些常见选项。 Type 列标识 optval 参数寻址的数据类型。 “说明”列提供有关套接字选项的一些基本信息。 有关套接字选项的更完整列表以及 (默认值的详细信息,例如) ,请参阅 套接字选项下的详细主题。

水平 = SOL_SOCKET

Value 类型 说明
SO_BROADCAST BOOL 配置用于发送广播数据的套接字。
SO_CONDITIONAL_ACCEPT BOOL 允许传入连接由应用程序接受或拒绝,而不是由协议堆栈接受或拒绝。
SO_DEBUG BOOL 启用调试输出。 Microsoft 提供程序当前不输出任何调试信息。
SO_DONTLINGER BOOL 不会阻止关闭等待发送未发送的数据。 设置此选项等效于将 l_onoff设置为零 设置SO_LINGER。
SO_DONTROUTE BOOL 设置是否应在套接字绑定到的接口上发送传出数据,而不是在其他接口上路由。 ATM 套接字不支持此选项, (导致错误) 。
SO_GROUP_PRIORITY int 保留。
SO_KEEPALIVE BOOL 启用为套接字连接发送保持活动数据包。 ATM 套接字不支持 (导致错误) 。
SO_LINGER 萦绕 如果存在未输入的数据,则延迟关闭。
SO_OOBINLINE BOOL 指示应随常规数据一起返回超出边界的数据。 此选项仅适用于支持带外数据的面向连接的协议。 有关本主题的讨论,请参阅 协议独立带外数据
SO_RCVBUF int 指定为接收保留的每个套接字缓冲区空间的总量。
SO_REUSEADDR BOOL 允许将套接字绑定到已在使用中的地址。 有关详细信息,请参阅 绑定。 不适用于 ATM 套接字。
SO_EXCLUSIVEADDRUSE BOOL 使套接字能够为独占访问进行绑定。 不需要管理权限。
SO_RCVTIMEO DWORD 设置用于阻止接收调用的超时(以毫秒为单位)。
SO_SNDBUF int 指定为发送保留的每个套接字缓冲区空间的总量。
SO_SNDTIMEO DWORD 用于阻止发送调用的超时(以毫秒为单位)。
SO_UPDATE_ACCEPT_CONTEXT int 使用侦听套接字的上下文汇报接受套接字。
PVD_CONFIG 服务提供程序依赖 此对象存储 与套接字关联的服务提供商的配置信息。 此数据结构的确切格式特定于服务提供商。
  有关 级别 = SOL_SOCKET套接字选项的更完整和详细信息,请参阅 SOL_SOCKET套接字选项

水平 = IPPROTO_TCP

请参阅IPPROTO_TCP套接字选项中的TCP_NODELAY。 另请参阅该主题,了解有关 级别 = IPPROTO_TCP套接字选项的更完整和详细信息。

水平 = NSPROTO_IPX

Value 类型 说明
IPX_PTYPE int 设置 IPX 数据包类型。
IPX_FILTERPTYPE int 设置接收筛选器数据包类型
IPX_STOPFILTERPTYPE int 停止筛选具有IPX_FILTERTYPE的筛选器类型集
IPX_DSTYPE int 设置发送的每个数据包的 SPX 标头中数据流字段的值。
IPX_EXTENDED_ADDRESS BOOL 设置是否启用扩展寻址。
IPX_RECVHDR BOOL 设置是否在所有接收标头上发送协议标头。
IPX_RECEIVE_BROADCAST BOOL 指示广播数据包可能位于套接字上。 默认情况下设置为 TRUE 。 不使用广播的应用程序应将此设置为 FALSE ,以提高系统性能。
IPX_IMMEDIATESPXACK BOOL 指示 SPX 连接在发送 ACK 之前不会延迟。 没有来回流量的应用程序应将此设置为 TRUE 以提高性能。
 

有关 级别 = NSPROTO_IPX套接字选项的更完整和详细信息,请参阅 NSPROTO_IPX套接字选项

下表显示了 setsockopt 不支持的 BSD 选项。

Value 类型 说明
SO_ACCEPTCONN BOOL 返回套接字是否处于侦听模式。 此选项仅适用于面向连接的协议。 此设置不支持此套接字选项。
SO_RCVLOWAT int BSD UNIX 提供的套接字选项,用于向后兼容。 此选项设置套接字输入操作要处理的最小字节数。
SO_SNDLOWAT int BSD UNIX 提供的套接字选项,用于向后兼容。 此选项设置套接字输出操作要处理的最小字节数。
SO_TYPE int 返回给定套接字的套接字类型 (SOCK_STREAM或SOCK_DGRAM,例如,设置套接字类型不支持此套接字选项。
 
注意 发出阻止 Winsock 调用(如 setsockopt)时,Winsock 可能需要等待网络事件,然后调用才能完成。 在这种情况下,Winsock 会执行可警报的等待,这可以通过异步过程调用 (APC) 在同一线程上计划的异步过程调用中断。 在同一线程上中断持续阻塞 Winsock 调用的 APC 中发出另一个阻止 Winsock 调用将导致未定义的行为,并且永远不会由 Winsock 客户端尝试。
 

示例代码

以下示例演示 setsockopt 函数。
#ifndef UNICODE
#define UNICODE
#endif

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>

// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")

int main()
{

    //---------------------------------------
    // Declare variables
    WSADATA wsaData;

    SOCKET ListenSocket;
    sockaddr_in service;

    int iResult = 0;

    BOOL bOptVal = FALSE;
    int bOptLen = sizeof (BOOL);

    int iOptVal = 0;
    int iOptLen = sizeof (int);

    //---------------------------------------
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != NO_ERROR) {
        wprintf(L"Error at WSAStartup()\n");
        return 1;
    }
    //---------------------------------------
    // Create a listening socket
    ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (ListenSocket == INVALID_SOCKET) {
        wprintf(L"socket function failed with error: %u\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }
    //---------------------------------------
    // 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);

    iResult = bind(ListenSocket, (SOCKADDR *) & service, sizeof (service));
    if (iResult == SOCKET_ERROR) {
        wprintf(L"bind failed with error %u\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }
    //---------------------------------------
    // Initialize variables and call setsockopt. 
    // The SO_KEEPALIVE parameter is a socket option 
    // that makes the socket send keepalive messages
    // on the session. The SO_KEEPALIVE socket option
    // requires a boolean value to be passed to the
    // setsockopt function. If TRUE, the socket is
    // configured to send keepalive messages, if FALSE
    // the socket configured to NOT send keepalive messages.
    // This section of code tests the setsockopt function
    // by checking the status of SO_KEEPALIVE on the socket
    // using the getsockopt function.

    bOptVal = TRUE;

    iResult = getsockopt(ListenSocket, SOL_SOCKET, SO_KEEPALIVE, (char *) &iOptVal, &iOptLen);
    if (iResult == SOCKET_ERROR) {
        wprintf(L"getsockopt for SO_KEEPALIVE failed with error: %u\n", WSAGetLastError());
    } else
        wprintf(L"SO_KEEPALIVE Value: %ld\n", iOptVal);

    iResult = setsockopt(ListenSocket, SOL_SOCKET, SO_KEEPALIVE, (char *) &bOptVal, bOptLen);
    if (iResult == SOCKET_ERROR) {
        wprintf(L"setsockopt for SO_KEEPALIVE failed with error: %u\n", WSAGetLastError());
    } else
        wprintf(L"Set SO_KEEPALIVE: ON\n");

    iResult = getsockopt(ListenSocket, SOL_SOCKET, SO_KEEPALIVE, (char *) &iOptVal, &iOptLen);
    if (iResult == SOCKET_ERROR) {
        wprintf(L"getsockopt for SO_KEEPALIVE failed with error: %u\n", WSAGetLastError());
    } else
        wprintf(L"SO_KEEPALIVE Value: %ld\n", iOptVal);

    closesocket(ListenSocket);
    WSACleanup();
    return 0;
}


IrDA 套接字的说明

使用适用于 IrDA 的 Windows 套接字开发应用程序时,请注意以下事项:

  • 必须显式包含 Af_irda.h 头文件。
  • IrDA 提供以下套接字选项:
    Value 类型 含义
    IRLMP_IAS_SET *IAS_SET 设置 IAS 属性
     

IRLMP_IAS_SET套接字选项使应用程序能够在本地 IAS 中设置单个类的单个属性。 应用程序指定要设置的类、属性和属性类型。 应用程序应为传递的参数分配所需大小的缓冲区。

IrDA 提供存储基于 IrDA 的信息的 IAS 数据库。 通过 Windows 套接字 2 接口提供对 IAS 数据库的有限访问,但应用程序通常不使用此类访问,并且主要支持与不符合 Windows 套接字 2 IrDA 约定的非 Windows 设备的连接。

以下结构 IAS_SET用于IRLMP_IAS_SET setsockopt 选项来管理本地 IAS 数据库:


// #include <Af_irda.h> for this struct

typedef struct _IAS_SET {
    u_char      irdaClassName[IAS_MAX_CLASSNAME];
    char      irdaAttribName[IAS_MAX_ATTRIBNAME];
    u_long    irdaAttribType;
    union
    {
              LONG irdaAttribInt;
              struct
              {
                   u_long   Len;
                   u_char    OctetSeq[IAS_MAX_OCTET_STRING];
              } irdaAttribOctetSeq;
              struct
              {
                   u_long    Len;
                   u_long    CharSet;
                   u_char    UsrStr[IAS_MAX_USER_STRING];
              } irdaAttribUsrStr;
    } irdaAttribute;
} IAS_SET, *PIAS_SET, FAR *LPIASSET;

以下结构 IAS_QUERY用于IRLMP_IAS_QUERY setsockopt 选项来查询对等方的 IAS 数据库:


// #include <Af_irda.h> for this struct

typedef struct _WINDOWS_IAS_QUERY {
        u_char   irdaDeviceID[4];
        char     irdaClassName[IAS_MAX_CLASSNAME];
        char     irdaAttribName[IAS_MAX_ATTRIBNAME];
        u_long   irdaAttribType;
        union
        {
                  LONG    irdaAttribInt;
                  struct
                  {
                          u_long  Len;
                          u_char  OctetSeq[IAS_MAX_OCTET_STRING];
                  } irdaAttribOctetSeq;
                  struct
                  {
                          u_long  Len;
                          u_long  CharSet;
                          u_char  UsrStr[IAS_MAX_USER_STRING];
                  } irdaAttribUsrStr;
        } irdaAttribute;
} IAS_QUERY, *PIAS_QUERY, FAR *LPIASQUERY;

许多SO_级套接字选项对 IrDA 没有意义。 仅支持SO_LINGER。

Windows Phone 8:Windows Phone 8 及更高版本上Windows Phone应用商店应用支持此函数。

Windows 8.1Windows 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

请参阅

IPPROTO_IP套接字选项

IPPROTO_IPV6套接字选项

IPPROTO_RM套接字选项

IPPROTO_TCP套接字选项

IPPROTO_UDP套接字选项

NSPROTO_IPX套接字选项

SOL_APPLETALK套接字选项

SOL_IRLMP套接字选项

SOL_SOCKET套接字选项

套接字选项

WSAAsyncSelect

WSAEventSelect

WSAIoctl

Winsock 函数

bind

getsockopt

ioctlsocket

socket