socket 函数 (winsock2.h)
套接字函数创建绑定到特定传输服务提供程序的套接字。
语法
SOCKET WSAAPI socket(
[in] int af,
[in] int type,
[in] int protocol
);
参数
[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) ,因此可以使用任一常量。
下表列出了地址系列的常见值,尽管许多其他值是可能的。
Af | 含义 |
---|---|
|
地址系列未指定。 |
|
Internet 协议版本 4 (IPv4) 地址系列。 |
|
IPX/SPX 地址系列。 仅当安装了 NWLink IPX/SPX NetBIOS 兼容传输协议时,才支持此地址系列。
Windows Vista 及更高版本不支持此地址系列。 |
|
AppleTalk 地址系列。 仅当安装了 AppleTalk 协议时,才支持此地址系列。
Windows Vista 及更高版本不支持此地址系列。 |
|
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 编程接口。 |
|
Internet 协议版本 6 (IPv6) 地址系列。 |
|
IrDA (IrDA) 地址系列。
仅当计算机安装了红外端口和驱动程序时,才支持此地址系列。 |
|
蓝牙地址系列。
如果计算机安装了蓝牙适配器和驱动程序,则 SP2 或更高版本的 Windows XP 支持此地址系列。 |
[in] type
新套接字的类型规范。
套接字类型的可能值在 Winsock2.h 头文件中定义。
下表列出了 Windows 套接字 2 支持 的类型 参数的可能值:
类型 | 含义 |
---|---|
|
一种套接字类型,它通过 OOB 数据传输机制提供排序的、可靠的双向、基于连接的字节流。 此套接字类型对 Internet 地址系列 (AF_INET 或AF_INET6) 使用传输控制协议 (TCP) 。 |
|
支持数据报的套接字类型,这些数据报是固定 (通常较小) 最大长度的无连接、不可靠的缓冲区。 此套接字类型对 Internet 地址系列 (AF_INET 或AF_INET6) 使用用户数据报协议 (UDP) 。 |
|
一种套接字类型,它提供允许应用程序操作下一层协议标头的原始套接字。 若要操作 IPv4 标头,必须在套接字上设置 IP_HDRINCL 套接字选项。 若要操作 IPv6 标头,必须在套接字上设置 IPV6_HDRINCL 套接字选项。 |
|
提供可靠消息数据报的套接字类型。 此类型的一个示例是 Windows 中的实用常规多播 (PGM) 多播协议实现,通常称为 可靠多播编程。
仅当安装了可靠多播协议时,才支持此 类型 值。 |
|
提供基于数据报的伪流数据包的套接字类型。 |
在 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 数据包标头的协议字段中设置。
下表列出了 协议 的常见值,尽管许多其他值是可能的。
返回值
如果未发生错误, 套接字 将返回引用新套接字的描述符。 否则,将返回值 INVALID_SOCKET,并且可以通过调用 WSAGetLastError 来检索特定的错误代码。
错误代码 | 含义 |
---|---|
在使用此函数之前,必须成功调用 WSAStartup 。 | |
网络子系统或关联的服务提供商发生故障。 | |
:不支持指定的地址系列。 例如,应用程序尝试为 AF_IRDA 地址系列创建套接字,但未在本地计算机上安装红外适配器和设备驱动程序。 | |
阻止 Windows 套接字 1.1 调用正在进行,或者服务提供商仍在处理回调函数。 | |
无法提供更多套接字描述符。 | |
提供的参数无效。 如果 af 参数设置为 AF_UNSPEC 且类型和协议参数未指定,则返回此错误。 | |
服务提供商返回了 2.2 以外的版本。 | |
服务提供商向 WSPStartup 返回了无效或不完整的过程表。 | |
未提供任何缓冲区空间。 无法创建套接字。 | |
指定的协议不受支持。 | |
指定的协议是此套接字的错误类型。 | |
服务提供程序初始化失败。 如果分层服务提供程序 (LSP) 或命名空间提供程序安装不正确或提供程序无法正常运行,则返回此错误。 | |
:在此地址系列中,不支持指定的套接字类型。 |
注解
套接字函数会导致分配套接字描述符和任何相关资源并将其绑定到特定的传输服务提供程序。 Winsock 将使用第一个可用的服务提供程序,该提供程序支持所请求的地址系列、套接字类型和协议参数的组合。 创建的套接字将具有重叠属性作为默认值。 对于 Windows,Mswsock.h 中定义的特定于 Microsoft 的套接字选项SO_OPENTYPE可能会影响此默认值。 有关SO_OPENTYPE的详细说明,请参阅特定于 Microsoft 的文档。
可以使用 WSASocket 创建没有重叠属性的套接字。 如果与重叠操作相关的参数的值为 NULL,则允许 (WSASend、WSARecv、WSASendTo、WSARecvFrom 和 WSAIoctl) 的所有函数也支持在重叠套接字上使用非重叠操作。
选择协议及其支持服务提供商时,此过程将仅选择基本协议或协议链,而不是协议层本身。 未链的协议层不被视为在 类型 或 af 上具有部分匹配项。 也就是说,如果未找到合适的协议,则它们不会导致 WSAEAFNOSUPPORT 或 WSAEPROTONOSUPPORT 的错误代码。
面向连接的套接字(如 SOCK_STREAM )提供全双工连接,并且必须处于连接状态,然后才能发送或接收任何数据。 使用 连接 调用创建到另一个套接字的连接。 连接后,可以使用 发送 和 recv 调用传输数据。 会话完成后,必须执行 closesocket 。
用于实现面向连接的可靠套接字的通信协议可确保数据不会丢失或重复。 如果对等协议具有缓冲区空间的数据无法在合理的时间内成功传输,则认为连接断开,后续调用将失败,错误代码设置为 WSAETIMEDOUT。
无连接、面向消息的套接字允许使用 sendto 和 recvfrom 向任意对等方发送和接收数据报。 如果此类套接字连接到特定对等方,则可以使用 send 将数据报发送到该对等方,并且只能使用 recv 从此对等方接收数据报。
接收具有SOCK_RAW类型的套接字时,IPv6 和 IPv4 的运行方式不同。 IPv4 接收数据包包括数据包有效负载、下一个上层标头 (例如,TCP 或 UDP 数据包) 的 IP 标头以及 IPv4 数据包标头。 IPv6 接收数据包包括数据包有效负载和下一个上层标头。 IPv6 接收数据包绝不包括 IPv6 数据包标头。
当通过 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。
示例代码
下面的示例演示如何使用 套接字 函数创建绑定到特定传输服务提供程序的套接字。#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 应用商店应用支持此函数。
要求
要求 | 值 |
---|---|
最低受支持的客户端 | Windows 8.1、Windows Vista [桌面应用 |UWP 应用] |
最低受支持的服务器 | Windows Server 2003 [桌面应用 | UWP 应用] |
目标平台 | Windows |
标头 | winsock2.h |
Library | Ws2_32.lib |
DLL | Ws2_32.dll |