[in] af

地址系列规范。 地址系列的可能值在 Winsock2.h 头文件中定义。

在为 Windows Vista 及更高版本发布的Windows SDK中,头文件的组织方式已更改,地址系列的可能值在 Ws2def.h 头文件中定义。 请注意, Ws2def.h 头文件会自动包含在 Winsock2.h 中 ,永远不应直接使用。

当前支持的值是 AF_INET 或 AF_INET6,它们是 IPv4 和 IPv6 的 Internet 地址系列格式。 用于 NetBIOS 的地址系列 (AF_NETBIOS 的其他选项,例如,如果安装了地址系列的 Windows 套接字服务提供商,则支持) 。 请注意,AF_地址系列和PF_协议系列常量的值 (相同,例如 ,AF_INET 和 PF_INET ) ,因此可以使用任一常量。

下表列出了地址系列的常见值,尽管许多其他值是可能的。

NetBIOS 地址系列。 仅当安装了适用于 NetBIOS 的 Windows 套接字提供程序时,才支持此地址系列。

32 位版本的 Windows 支持 NetBIOS 的 Windows 套接字提供程序。 默认情况下,此提供程序安装在 32 位版本的 Windows 上。

64 位版本的 Windows 不支持 NetBIOS 的 Windows 套接字提供程序,包括 Windows 7、Windows Server 2008、Windows Vista、Windows Server 2003 或 Windows XP。

适用于 NetBIOS 的 Windows 套接字提供程序仅支持 类型 参数设置为 SOCK_DGRAM 的套接字。

适用于 NetBIOS 的 Windows 套接字提供程序与 NetBIOS 编程接口不直接相关。 Windows Vista、Windows Server 2008 及更高版本不支持 NetBIOS 编程接口。

在 Windows 套接字 2 中,引入了新的套接字类型。 应用程序可以通过 WSAEnumProtocols 函数动态发现每个可用传输协议的属性。 因此,应用程序可以确定地址系列的可能的套接字类型和协议选项,并在指定此参数时使用此信息。 Winsock2.h 和 Ws2def.h 头文件中的套接字类型定义将随着新的套接字类型、地址系列和协议的定义而定期更新。

在 Windows 套接字 1.1 中,唯一可能的套接字类型是 SOCK_DGRAM 和 SOCK_STREAM 。

[in] protocol

要使用的协议。 协议 参数的可能选项特定于指定的地址系列和套接字类型。 协议 的可能值在 Winsock2.h 和 Wsrm.h 头文件中定义。

在 Windows Vista 及更高版本发布的Windows SDK中,头文件的组织方式已更改,此参数可以是 Ws2def.h 头文件中定义的 IPPROTO 枚举类型中的值之一。 请注意, Ws2def.h 头文件会自动包含在 Winsock2.h 中 ,永远不应直接使用。

如果指定值 0,则调用方不希望指定协议,服务提供商将选择要使用的 协议 。

当 af 参数AF_INET或AF_INET6且 类型 为SOCK_RAW 时,为 协议 指定的值在 IPv6 或 IPv4 数据包标头的协议字段中设置。

下表列出了 协议 的常见值,尽管许多其他值是可能的。

protocol Internet 控制消息协议 (ICMP) 。 当 af 参数 AF_UNSPEC 、 AF_INET 或 AF_INET6 且 类型 参数 SOCK_RAW 或未指定时,此值可能为 。

Windows XP 及更高版本支持此 协议 值。

Internet 组管理协议 (IGMP) 。 当 af 参数 AF_UNSPEC 、 AF_INET 或 AF_INET6 且 类型 参数 SOCK_RAW 或未指定时,此值可能为 。

Windows XP 及更高版本支持此 协议 值。

Internet 控制消息协议版本 6 (ICMPv6) 。 当 af 参数 AF_UNSPEC 、 AF_INET 或 AF_INET6 且 类型 参数 SOCK_RAW 或未指定时,此值可能为 。

Windows XP 及更高版本支持此 协议 值。

可靠多播的 PGM 协议。 当 af 参数AF_INET且 类型 参数 SOCK_RDM 时,这是一个可能 的值。 在 Windows Vista 及更高版本发布的Windows SDK中,此协议也称为 IPPROTO_PGM 。

仅当安装了可靠多播 协议 时,才支持此协议值。

如果未发生错误, 套接字 将返回引用新套接字的描述符。 否则,将返回值 INVALID_SOCKET,并且可以通过调用 WSAGetLastError 来检索特定的错误代码。

套接字 函数会导致分配套接字描述符和任何相关资源并将其绑定到特定的传输服务提供程序。 Winsock 将使用第一个可用的服务提供程序,该提供程序支持所请求的地址系列、套接字类型和协议参数的组合。 创建的套接字将具有重叠属性作为默认值。 对于 Windows,Mswsock.h 中定义的特定于 Microsoft 的套接字选项SO_OPENTYPE可能会影响此默认值。 有关SO_OPENTYPE的详细说明,请参阅特定于 Microsoft 的文档。

可以使用 WSASocket 创建没有重叠属性的套接字。 如果与重叠操作相关的参数的值为 NULL ,则允许 ( WSASend 、 WSARecv 、 WSASendTo 、 WSARecvFrom 和 WSAIoctl ) 的所有函数也支持在重叠套接字上使用非重叠操作。

选择协议及其支持服务提供商时,此过程将仅选择基本协议或协议链,而不是协议层本身。 未链的协议层不被视为在 类型 或 af 上具有部分匹配项。 也就是说,如果未找到合适的协议,则它们不会导致 WSAEAFNOSUPPORT 或 WSAEPROTONOSUPPORT 的错误代码。

注意 清单常 量AF_UNSPEC 继续在头文件中定义,但强烈建议不要使用它,因为这样可能会导致 解释协议 参数的值不明确。 建议应用程序将 AF_INET6 用于 af 参数,并创建可与 IPv4 和 IPv6 一起使用的双模式套接字。

面向连接的套接字(如 SOCK_STREAM )提供全双工连接,并且必须处于连接状态,然后才能发送或接收任何数据。 使用 连接 调用创建到另一个套接字的连接。 连接后,可以使用 发送 和 recv 调用传输数据。 会话完成后,必须执行 closesocket 。

用于实现面向连接的可靠套接字的通信协议可确保数据不会丢失或重复。 如果对等协议具有缓冲区空间的数据无法在合理的时间内成功传输,则认为连接断开,后续调用将失败,错误代码设置为 WSAETIMEDOUT 。

无连接、面向消息的套接字允许使用 sendto 和 recvfrom 向任意对等方发送和接收数据报。 如果此类套接字连接到特定对等方,则可以使用 send 将数据报发送到该对等方,并且只能使用 recv 从此对等方接收数据报。

接收具有 SOCK_RAW 类型的 套接字时,IPv6 和 IPv4 的运行方式不同。 IPv4 接收数据包包括数据包有效负载、下一个上层标头 (例如,TCP 或 UDP 数据包) 的 IP 标头以及 IPv4 数据包标头。 IPv6 接收数据包包括数据包有效负载和下一个上层标头。 IPv6 接收数据包绝不包括 IPv6 数据包标头。

注意 在Windows NT,原始套接字支持需要管理权限。 类型 参数为 SOCK_SEQPACKET 的套接字基于数据报,但充当伪流协议。 对于发送和接收数据包,使用单独的数据报。 但是,Windows 套接字可以将多个接收数据包合并为单个数据包。 因此,应用程序可以发出接收调用 (例如, recv 或 WSARecvEx ) ,并在单个调用中检索多个合并的多个数据包中的数据。 AF_NETBIOS地址系列支持 SOCK_SEQPACKET 的类型 参数。

当通过 TCP/IP 为 NetBIOS AF_NETBIOS af 参数时 ,类型参数可以是 SOCK_DGRAM 或 SOCK_SEQPACKET 。 对于 AF_NETBIOS 地址系列, 协议 参数是表示为负数的 LAN 适配器编号。

在 Windows XP 及更高版本中,以下命令可用于列出 Windows 套接字目录,以确定安装的服务提供商以及支持的地址系列、套接字类型和协议。

netsh winsock show catalog

不需要支持 类型为 SOCK_RAW 的套接字,但建议服务提供商尽可能支持原始套接字。

IrDA 套接字说明 请记住以下几点:
  • 必须显式包含 Af_irda.h 头文件。
  • 仅支持 SOCK_STREAM ;IrDA 不支持 SOCK_DGRAM 类型。
  • 对于 IrDA, 协议 参数始终设置为 0。
  • 仅当本地计算机安装了红外端口和驱动程序时,才能创建与 AF_IRDA 地址系列配合使用的套接字。 否则,对 将 af 参数设置为 AF_IRDA 的 套接字 函数的调用将失败,
    并且 WSAGetLastError 返回 WSAEPROTONOSUPPORT 。 下面的示例演示如何使用 套接字 函数创建绑定到特定传输服务提供程序的套接字。
    #ifndef UNICODE
    #define UNICODE 1
    #endif
    // link with Ws2_32.lib
    #pragma comment(lib,"Ws2_32.lib")
    #include <winsock2.h>
    #include <ws2tcpip.h>
    #include <stdio.h>
    #include <stdlib.h>   // Needed for _wtoi
    int __cdecl wmain(int argc, wchar_t **argv)
        //-----------------------------------------
        // Declare and initialize variables
        WSADATA wsaData = {0};
        int iResult = 0;
    //    int i = 1;
        SOCKET sock = INVALID_SOCKET;
        int iFamily = AF_UNSPEC;
        int iType = 0;
        int iProtocol = 0;
        // Validate the parameters
        if (argc != 4) {
            wprintf(L"usage: %s <addressfamily> <type> <protocol>\n", argv[0]);
            wprintf(L"socket opens a socket for the specified family, type, & protocol\n");
            wprintf(L"%ws example usage\n", argv[0]);
            wprintf(L"   %ws 0 2 17\n", argv[0]);
            wprintf(L"   where AF_UNSPEC=0 SOCK_DGRAM=2 IPPROTO_UDP=17\n", argv[0]);
            return 1;
        iFamily = _wtoi(argv[1]);
        iType = _wtoi(argv[2]);
        iProtocol = _wtoi(argv[3]);
        // Initialize Winsock
        iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
        if (iResult != 0) {
            wprintf(L"WSAStartup failed: %d\n", iResult);
            return 1;
        wprintf(L"Calling socket with following parameters:\n");
        wprintf(L"  Address Family = ");
        switch (iFamily) {
        case AF_UNSPEC:
            wprintf(L"Unspecified");
            break;
        case AF_INET:
            wprintf(L"AF_INET (IPv4)");
            break;
        case AF_INET6:
            wprintf(L"AF_INET6 (IPv6)");
            break;
        case AF_NETBIOS:
            wprintf(L"AF_NETBIOS (NetBIOS)");
            break;
        case AF_BTH:
            wprintf(L"AF_BTH (Bluetooth)");
            break;
        default:
            wprintf(L"Other");
            break;
        wprintf(L" (%d)\n", iFamily);
        wprintf(L"  Socket type = ");
        switch (iType) {
        case 0:
            wprintf(L"Unspecified");
            break;
        case SOCK_STREAM:
            wprintf(L"SOCK_STREAM (stream)");
            break;
        case SOCK_DGRAM:
            wprintf(L"SOCK_DGRAM (datagram)");
            break;
        case SOCK_RAW:
            wprintf(L"SOCK_RAW (raw)");
            break;
        case SOCK_RDM:
            wprintf(L"SOCK_RDM (reliable message datagram)");
            break;
        case SOCK_SEQPACKET:
            wprintf(L"SOCK_SEQPACKET (pseudo-stream packet)");
            break;
        default:
            wprintf(L"Other");
            break;
        wprintf(L" (%d)\n", iType);
        wprintf(L"  Protocol = %d = ", iProtocol);
        switch (iProtocol) {
        case 0:
            wprintf(L"Unspecified");
            break;
        case IPPROTO_ICMP:
            wprintf(L"IPPROTO_ICMP (ICMP)");
            break;
        case IPPROTO_IGMP:
            wprintf(L"IPPROTO_IGMP (IGMP)");
            break;
        case IPPROTO_TCP:
            wprintf(L"IPPROTO_TCP (TCP)");
            break;
        case IPPROTO_UDP:
            wprintf(L"IPPROTO_UDP (UDP)");
            break;
        case IPPROTO_ICMPV6:
            wprintf(L"IPPROTO_ICMPV6 (ICMP Version 6)");
            break;
        default:
            wprintf(L"Other");
            break;
        wprintf(L" (%d)\n", iProtocol);
        sock = socket(iFamily, iType, iProtocol);
        if (sock == INVALID_SOCKET) 
            wprintf(L"socket function failed with error = %d\n", WSAGetLastError() );
        else {
            wprintf(L"socket function succeeded\n");
            // Close the socket to release the resources associated
            // Normally an application calls shutdown() before closesocket 
            //   to  disables sends or receives on a socket first
            // This isn't needed in this simple sample
            iResult = closesocket(sock);
            if (iResult == SOCKET_ERROR) {
                wprintf(L"closesocket failed with error = %d\n", WSAGetLastError() );
                WSACleanup();
                return 1;
        WSACleanup();
        return 0;
                  Windows Phone 8:Windows Phone 8 及更高版本上的 Windows Phone 应用商店应用支持此函数。

    Windows 8.1和Windows Server 2012 R2:Windows 8.1、Windows Server 2012 R2 及更高版本的 Windows 应用商店应用支持此函数。