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 的因特網位址系列格式。 如果已安裝位址系列 Windows Sockets 服務提供者,則支援與 NetBIOS 搭配使用的位址系列 (AF_NETBIOS 的其他選項,例如) 。 請注意,AF_位址系列和PF_通訊協定系列常數的值 (相同,例如, AF_INET 和 PF_INET) ,因此可以使用任一個常數。
下表列出位址系列常見的值,但可能有許多其他值。
Af | 意義 |
---|---|
|
未指定位址系列。 |
|
因特網通訊協定第 4 版 (IPv4) 位址系列。 |
|
IPX/SPX 位址系列。 只有在安裝 NWLink IPX/SPX NetBIOS 相容傳輸通訊協定時,才支援此位址系列。
Windows Vista 和更新版本不支援此位址系列。 |
|
AppleTalk 位址系列。 只有在安裝 AppleTalk 通訊協定時,才支援此位址系列。
Windows Vista 和更新版本不支援此位址系列。 |
|
NetBIOS 位址系列。 只有在已安裝 NetBIOS 的 Windows Sockets 提供者時,才支援此位址系列。
32 位版本的 Windows 支援 NetBIOS 的 Windows 套接字提供者。 此提供者預設會安裝在32位版本的Windows上。 64 位版本的 Windows 不支援 NetBIOS 的 Windows Sockets 提供者,包括 Windows 7、Windows Server 2008、Windows Vista、Windows Server 2003 或 Windows XP。 NetBIOS 的 Windows Sockets 提供者僅支援 類型 參數設定為 SOCK_DGRAM的套接字。 NetBIOS 的 Windows Sockets 提供者與 NetBIOS 程式設計介面不直接相關。 Windows Vista、Windows Server 2008 及更新版本不支援 NetBIOS 程式設計介面。 |
|
因特網通訊協定第 6 版 (IPv6) 位址系列。 |
|
IrDA (IrDA) 位址系列。
只有在計算機已安裝基礎結構埠和驅動程式時,才支援此位址系列。 |
|
藍牙位址系列。
如果計算機已安裝藍牙適配卡和驅動程式,Windows XP 上的SP2或更新版本支援此位址系列。 |
[in] type
新套接字的類型規格。
套接字類型的可能值定義在 Winsock2.h 頭檔中。
下表列出 Windows Sockets 2 所支援 之類型 參數的可能值:
類型 | 意義 |
---|---|
|
套接字類型,提供具有 OOB 數據傳輸機制的循序、可靠、雙向、以連線為基礎的位元組數據流。 此套接字類型會針對因特網位址系列 (AF_INET 或AF_INET6) 使用传输控制通讯协议 (TCP) 。 |
|
支援數據報的套接字類型,這些數據報是無連接、不可靠的固定 (通常很小) 最大長度。 此套接字類型會針對因特網位址系列 (AF_INET 或AF_INET6) 使用用户数据报通讯协议 (UDP) 。 |
|
提供原始套接字的套接字類型,可讓應用程式操作下一層通訊協議標頭。 若要操作 IPv4 標頭,必須在套接字上設定 IP_HDRINCL 套接字選項。 若要操作 IPv6 標頭,必須在套接字上設定 IPV6_HDRINCL 套接字選項。 |
|
提供可靠訊息數據報的套接字類型。 此類型的範例是 Windows 中的「實用一般多播」 (PGM) 多播通訊協議實作,通常稱為 可靠的多播程序設計。
只有在安裝可靠的多播通訊協定時,才支援 此類型 值。 |
|
套接字類型,提供以數據報為基礎的虛擬數據流封包。 |
在 Windows Sockets 2 中,引進了新的套接字類型。 應用程式可以透過 WSAEnumProtocols 函式動態探索每個可用傳輸通訊協議的屬性。 因此,應用程式可以判斷位址系列可能的套接字類型和通訊協定選項,並在指定此參數時使用此資訊。 Winsock2.h 和 Ws2def.h 頭檔中的套接字類型定義會定期更新,因為定義了新的套接字類型、位址系列和通訊協定。
在 Windows Sockets 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 Sockets 1.1 呼叫正在進行中,或服務提供者仍在處理回呼函式。 | |
不再有可用的通訊端描述項。 | |
提供的引數無效。 如果 af 參數設定為 AF_UNSPEC且未指定類型和通訊協定參數,則會傳回此錯誤。 | |
服務提供者傳回 2.2 以外的版本。 | |
服務提供者將無效或不完整的程式表傳回至 WSPStartup。 | |
沒有可用的緩衝區空間。 無法建立套接字。 | |
不支援指定的通訊協定。 | |
指定的通訊協定是這個套接字的錯誤類型。 | |
服務提供者無法初始化。 如果分層服務提供者 (LSP) 或命名空間提供者安裝不正確,或提供者無法正確運作,就會傳回此錯誤。 | |
此位址系列不支援指定的套接字類型。 |
備註
套接字函式會導致套接字描述項和任何相關的資源配置並系結至特定的傳輸服務提供者。 Winsock 會利用第一個可用的服務提供者,以支援位址系列、套接字類型和通訊協定參數的要求組合。 所建立的套接字將會有重疊屬性做為預設值。 針對 Windows,在 Mswsock.h 中定義的 Microsoft 特定套接字選項SO_OPENTYPE可能會影響此預設值。 如需SO_OPENTYPE的詳細描述,請參閱 Microsoft 特定檔。
不使用重疊屬性的套接字可以使用 WSASocket 來建立。 如果與重疊作業相關的參數值為 NULL,則允許重疊作業 (WSASend、WSARecvTo、WSARecvFrom 和 WSAIoct) l 的所有函式也都支援重疊套接字上的非重疊用法。
選取通訊協定及其支持的服務提供者時,此程式只會選擇基底通訊協定或通訊協定鏈結,而不是本身的通訊協定層。 未鏈結的通訊協定層不會被視為 在類型 或 af 上具有部分相符專案。 也就是說,如果找不到適當的通訊協定,它們就不會造成 WSAEAFNOSUPPORT 或 WSAEPROTONOSUPPORT 的錯誤碼。
SOCK_STREAM之類的連線導向套接字提供全雙工連線,而且必須處於連線狀態,才能傳送或接收任何數據。 使用 連接 呼叫建立另一個套接字的連線。 線上之後,即可使用 傳送 和 重新傳送 呼叫來傳輸數據。 會話完成時,必須執行 closesocket 。
用來實作可靠、連線導向套接字的通訊協議可確保數據不會遺失或重複。 如果對等通訊協定具有緩衝區空間的數據無法在合理的時間內成功傳輸,則會將連線視為中斷,後續呼叫將會失敗,並將錯誤碼設定為 WSAETIMEDOUT。
無連接、訊息導向的套接字允許使用 sendto 和 recvfrom,在任意對等端傳送和接收數據報。 如果這類套接字連接到特定對等,可以使用 send 將數據報傳送至該對等,而且只能使用 recv 從這個對等接收。
當接收 類型 為 SOCK_RAW 的套接字時,IPv6 和 IPv4 的運作方式不同。 IPv4 接收封包包含封包承載、下一個上層標頭 (例如 TCP 或 UDP 封包的 IP 標頭) ,以及 IPv4 封包標頭。 IPv6 接收封包包含封包承載和下一個上層標頭。 IPv6 接收封包永遠不會包含IPv6 封包標頭。
當 NetBIOS 透過 TCP/IP AF_NETBIOSaf 參數時,可以SOCK_DGRAM或SOCK_SEQPACKET類型參數。 對於 AF_NETBIOS 位址系列, 通訊協議 參數是以負數表示的 LAN 適配卡編號。
在 Windows XP 和更新版本上,下列命令可用來列出 Windows Sockets 目錄,以判斷已安裝的服務提供者,以及支援的位址系列、套接字類型和通訊協定。
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 Store 應用程式支援此函式。
Windows 8.1 和 Windows Server 2012 R2:Windows 市集應用程式支援 Windows 8.1、Windows Server 2012 R2 及更新版本。
規格需求
需求 | 值 |
---|---|
最低支援的用戶端 | Windows 8.1、Windows Vista [傳統型應用程式 |UWP 應用程式] |
最低支援的伺服器 | Windows Server 2003 [傳統型應用程式 |UWP 應用程式] |
目標平台 | Windows |
標頭 | winsock2.h |
程式庫 | Ws2_32.lib |
Dll | Ws2_32.dll |