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 Sockets 1.1 调用正在进行,或者服务提供程序仍在处理回调函数。
WSAEINVAL
level 参数无效,或者 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

类型 说明
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 允许将套接字绑定到已在使用中的地址。 有关详细信息,请参阅 bind。 不适用于 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

类型 说明
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 选项。

类型 说明
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) 异步过程调用可能会中断该等待。 在 APC 内发出另一个阻止 Winsock 调用,该调用中断了同一线程上正在进行的阻止 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 提供以下套接字选项:
    类型 含义
    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