Поделиться через


Функция socket (winsock2.h)

Функция сокета создает сокет, привязанный к конкретному поставщику транспортных услуг.

Синтаксис

SOCKET WSAAPI socket(
  [in] int af,
  [in] int type,
  [in] int protocol
);

Параметры

[in] af

Спецификация семейства адресов. Возможные значения для семейства адресов определяются в файле заголовка Winsock2.h .

На Windows SDK, выпущенном для Windows Vista и более поздних версий, организация файлов заголовков изменилась, а возможные значения для семейства адресов определяются в файле заголовка Ws2def.h. Обратите внимание, что файл заголовка Ws2def.h автоматически включается в Winsock2.h и никогда не должен использоваться напрямую.

В настоящее время поддерживаются значения AF_INET или AF_INET6, которые представляют собой форматы семейства адресов Интернета для IPv4 и IPv6. Другие параметры семейства адресов (например, AF_NETBIOS для использования с NetBIOS) поддерживаются, если установлен поставщик служб Windows Sockets для семейства адресов. Обратите внимание, что значения для семейства адресов AF_ и констант семейства протоколов PF_ идентичны (например, AF_INET и PF_INET), поэтому можно использовать любой из констант.

В приведенной ниже таблице перечислены общие значения для семейства адресов, хотя возможны и многие другие значения.

Af Значение
AF_UNSPEC
0
Семейство адресов не указано.
AF_INET
2
Семейство адресов IPv4.
AF_IPX
6
Семейство адресов IPX/SPX. Это семейство адресов поддерживается, только если установлен протокол NWLink IPX/SPX NetBIOS.

Это семейство адресов не поддерживается в Windows Vista и более поздних версиях.

AF_APPLETALK
16
Семейство адресов AppleTalk. Это семейство адресов поддерживается только в том случае, если установлен протокол AppleTalk.

Это семейство адресов не поддерживается в Windows Vista и более поздних версиях.

AF_NETBIOS
17
Семейство адресов NetBIOS. Это семейство адресов поддерживается, только если установлен поставщик Сокетов Windows для NetBIOS.

Поставщик сокетов Windows для NetBIOS поддерживается в 32-разрядных версиях Windows. Этот поставщик устанавливается по умолчанию в 32-разрядных версиях Windows.

Поставщик сокетов Windows для NetBIOS не поддерживается в 64-разрядных версиях Windows, включая Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 или Windows XP.

Поставщик сокетов Windows для NetBIOS поддерживает только сокеты, для которых параметру type присвоено значение SOCK_DGRAM.

Поставщик сокетов Windows для NetBIOS не связан напрямую с программным интерфейсом NetBIOS . Программный интерфейс NetBIOS не поддерживается в Windows Vista, Windows Server 2008 и более поздних версиях.

AF_INET6
23
Семейство адресов IPv6.
AF_IRDA
26
Семейство адресов Ассоциации инфракрасных данных (IrDA).

Это семейство адресов поддерживается только в том случае, если на компьютере установлен инфракрасный порт и драйвер.

AF_BTH
32
Семейство адресов Bluetooth.

Это семейство адресов поддерживается в Windows XP с пакетом обновления 2 (SP2) или более поздней версии, если на компьютере установлены адаптер Bluetooth и драйвер.

[in] type

Спецификация типа для нового сокета.

Возможные значения для типа сокета определяются в файле заголовка Winsock2.h .

В следующей таблице перечислены возможные значения параметра типа , поддерживаемого для сокетов Windows 2.

Тип Значение
SOCK_STREAM
1
Тип сокета, который предоставляет виртуационные, надежные двусторонние потоки байтов на основе подключений с механизмом передачи данных OOB. Этот тип сокета использует протокол TCP для семейства интернет-адресов (AF_INET или AF_INET6).
SOCK_DGRAM
2
Тип сокета, поддерживающий датаграммы, которые являются ненадежными буферами фиксированной (обычно небольшой) максимальной длины без подключения. Этот тип сокета использует протокол UDP для семейства адресов Интернета (AF_INET или AF_INET6).
SOCK_RAW
3
Тип сокета, предоставляющий необработанный сокет, позволяющий приложению управлять следующим заголовком протокола верхнего уровня. Чтобы управлять заголовком IPv4, для сокета необходимо задать параметр сокета IP_HDRINCL . Чтобы управлять заголовком IPv6, для сокета необходимо задать параметр сокета IPV6_HDRINCL .
SOCK_RDM
4
Тип сокета, предоставляющий надежную датаграмму сообщений. Примером этого типа является реализация протокола прагматической общей многоадресной рассылки (PGM) в Windows, которую часто называют надежным многоадресным программированием.

Это значение типа поддерживается только в том случае, если установлен надежный протокол многоадресной рассылки.

SOCK_SEQPACKET
5
Тип сокета, предоставляющий пакет псевдопотока на основе датаграмм.
 

В Windows Sockets 2 появились новые типы сокетов. Приложение может динамически обнаруживать атрибуты каждого доступного транспортного протокола с помощью функции WSAEnumProtocols . Таким образом, приложение может определить возможный тип сокета и параметры протокола для семейства адресов и использовать эти сведения при указании этого параметра. Определения типов сокетов в файлах заголовков Winsock2.h и Ws2def.h будут периодически обновляться по мере определения новых типов сокетов, семейств адресов и протоколов.

В Windows Sockets 1.1 единственными возможными типами сокетов являются SOCK_DGRAM и SOCK_STREAM.

[in] protocol

Используемый протокол. Возможные параметры параметра протокола относятся к указанному семейству адресов и типу сокета. Возможные значения для протокола определяются в файлах заголовков Winsock2.h и Wsrm.h .

На Windows SDK, выпущенном для Windows Vista и более поздних версий, организация файлов заголовков изменилась, и этот параметр может быть одним из значений типа перечисления IPPROTO, определенного в файле заголовка Ws2def.h. Обратите внимание, что файл заголовка Ws2def.h автоматически включается в Winsock2.h и никогда не должен использоваться напрямую.

Если указано значение 0, вызывающий объект не хочет указывать протокол, и поставщик услуг выберет протокол для использования.

Если параметр af AF_INET или AF_INET6 и типSOCK_RAW, значение, указанное для протокола , задается в поле протокола заголовка пакета IPv6 или IPv4.

В приведенной ниже таблице перечислены общие значения для протокола , хотя возможны и многие другие значения.

protocol Значение
IPPROTO_ICMP
1
Протокол ICMP. Это возможное значение, если параметр af имеет значение AF_UNSPEC, AF_INET или AF_INET6 , а параметр typeSOCK_RAW или не указан.

Это значение протокола поддерживается в Windows XP и более поздних версиях.

IPPROTO_IGMP
2
Протокол IGMP. Это возможное значение, если параметр af имеет значение AF_UNSPEC, AF_INET или AF_INET6 , а параметр typeSOCK_RAW или не указан.

Это значение протокола поддерживается в Windows XP и более поздних версиях.

BTHPROTO_RFCOMM
3
Протокол радиочастотной связи Bluetooth (Bluetooth RFCOMM). Это возможное значение, если параметр afAF_BTH, а параметр typeSOCK_STREAM.

Это значение протокола поддерживается в Windows XP с пакетом обновления 2 (SP2) или более поздней версии.

IPPROTO_TCP
6
Протокол TCP. Это возможное значение, если параметр af имеет значение AF_INET или AF_INET6 , а параметр typeSOCK_STREAM.
IPPROTO_UDP
17
Протокол UDP. Это возможное значение, если параметр af имеет значение AF_INET или AF_INET6 , а параметр typeSOCK_DGRAM.
IPPROTO_ICMPV6
58
Протокол ICMPv6. Это возможное значение, если параметр af имеет значение AF_UNSPEC, AF_INET или AF_INET6 , а параметр typeSOCK_RAW или не указан.

Это значение протокола поддерживается в Windows XP и более поздних версиях.

IPPROTO_RM
113
Протокол PGM для надежной многоадресной рассылки. Это возможное значение, если параметр af имеет значение AF_INET , а параметр typeSOCK_RDM. В Windows SDK, выпущенном для Windows Vista и более поздних версий, этот протокол также называется IPPROTO_PGM.

Это значение протокола поддерживается только в том случае, если установлен надежный протокол многоадресной рассылки.

Возвращаемое значение

Если ошибка не возникает, сокет возвращает дескриптор, ссылающийся на новый сокет. В противном случае возвращается значение INVALID_SOCKET, а определенный код ошибки можно получить, вызвав WSAGetLastError.

Код ошибки Значение
WSANOTINITIALISED
Перед использованием этой функции должен быть выполнен успешный вызов WSAStartup .
WSAENETDOWN
Произошел сбой сетевой подсистемы или связанного поставщика услуг.
WSAEAFNOSUPPORT
Указанное семейство адресов не поддерживается. Например, приложение попыталось создать сокет для семейства адресов AF_IRDA , но на локальном компьютере не установлены инфракрасный адаптер и драйвер устройства.
WSAEINPROGRESS
Выполняется блокирующий вызов Windows Sockets 1.1 или поставщик услуг по-прежнему обрабатывает функцию обратного вызова.
WSAEMFILE
Больше нет доступных дескрипторов сокетов.
WSAEINVAL
Указан недопустимый аргумент. Эта ошибка возвращается, если для параметра af задано значение AF_UNSPEC а тип и параметр протокола не указан.
WSAEINVALIDPROVIDER
Поставщик услуг вернул версию, отличаемую от 2.2.
WSAEINVALIDPROCTABLE
Поставщик служб вернул в WSPStartup недопустимую или неполную таблицу процедур.
WSAENOBUFS
Нет свободного места в буфере. Не удается создать сокет.
WSAEPROTONOSUPPORT
Указанный протокол не поддерживается.
WSAEPROTOTYPE
Указанный протокол является неправильным типом для этого сокета.
WSAEPROVIDERFAILEDINIT
Поставщику услуг не удалось инициализировать. Эта ошибка возвращается, если поставщик многоуровневой службы (LSP) или поставщик пространства имен был неправильно установлен или поставщик не работает правильно.
WSAESOCKTNOSUPPORT
Указанный тип сокета не поддерживается в этом семействе адресов.

Комментарии

Функция сокета позволяет выделить дескриптор сокета и все связанные ресурсы и привязать их к конкретному поставщику транспортных услуг. Winsock будет использовать первый доступный поставщик услуг, который поддерживает запрошенное сочетание семейства адресов, типа сокета и параметров протокола. Созданный сокет будет иметь перекрывающийся атрибут по умолчанию. Для Windows параметр сокета майкрософт SO_OPENTYPE, определенный в Mswsock.h, может повлиять на это значение по умолчанию. Подробное описание SO_OPENTYPE см. в документации майкрософт.

Сокеты без перекрывающихся атрибутов можно создать с помощью WSASocket. Все функции, допускающие перекрывающиеся операции (WSASend, WSARecv, WSASendTo, WSARecvFrom и WSAIoctl), также поддерживают неперекрываемое использование перекрывающегося сокета, если значения параметров, связанных с перекрывающейся операцией, равны NULL.

При выборе протокола и поддерживающего его поставщика услуг эта процедура выбирает только базовый протокол или цепочку протоколов, а не уровень протокола сам по себе. Неоткреченные уровни протокола не считаются частичными совпадениями по типу или af . Это значит, что они не приводят к коду ошибки WSAEAFNOSUPPORT или WSAEPROTONOSUPPORT , если подходящий протокол не найден.

Примечание Константа манифеста AF_UNSPEC по-прежнему определяется в файле заголовка, но ее использование настоятельно не рекомендуется, так как это может привести к неоднозначности при интерпретации значения параметра протокола .
 
Приложениям рекомендуется использовать AF_INET6 для параметра af и создать двойной сокет, который можно использовать как с IPv4, так и с IPv6.

Сокеты, ориентированные на подключение, такие как SOCK_STREAM обеспечивают полнодуплексные подключения и должны находиться в подключенном состоянии, прежде чем можно будет отправлять или получать любые данные. Подключение к другому сокету создается с помощью вызова подключения . После подключения данные можно передавать с помощью вызовов send и recv . После завершения сеанса необходимо выполнить закрытие .

Протоколы связи, используемые для реализации надежного, ориентированного на подключение сокета, гарантируют, что данные не будут потеряны и не дублируются. Если данные, для которых одноранговый протокол имеет буферное пространство, не могут быть успешно переданы в течение разумного периода времени, подключение считается нарушенным, и последующие вызовы завершатся ошибкой с кодом ошибки WSAETIMEDOUT.

Сокеты без подключения, ориентированные на сообщения, позволяют отправлять и получать датаграммы произвольным одноранговым узлам и получать их с помощью sendto и recvfrom. Если такой сокет подключен к определенному однорангового узла, датаграммы можно отправлять на этот одноранговый узел с помощью метода send и получать только от этого однорангового узла с помощью recv.

IPv6 и IPv4 работают по-разному при получении сокета с типомSOCK_RAW. Пакет получения IPv4 включает полезные данные пакета, следующий заголовок верхнего уровня (например, IP-заголовок для пакета TCP или UDP) и заголовок пакета IPv4. Пакет получения IPv6 включает полезные данные пакета и следующий заголовок верхнего уровня. Пакет получения IPv6 никогда не содержит заголовок пакета IPv6.

Примечание На Windows NT для поддержки необработанных сокетов требуются права администратора.
 
Сокет с параметром типаSOCK_SEQPACKET основан на датаграммах, но функционирует как протокол псевдопотока. Для отправки и получения пакетов используются отдельные датаграммы. Однако сокеты Windows могут объединить несколько пакетов получения в один пакет. Таким образом, приложение может выполнить вызов приема (например, recv или WSARecvEx) и получить данные из нескольких объединенных пакетов в одном вызове. Семейство адресов AF_NETBIOS поддерживает параметр типаSOCK_SEQPACKET.

Если параметр afAF_NETBIOS для NetBIOS по протоколу TCP/IP, параметр type может быть SOCK_DGRAM или SOCK_SEQPACKET. Для семейства адресов AF_NETBIOS параметр протокола — это номер адаптера локальной сети, представленный в виде отрицательного числа.

В Windows XP и более поздних версиях следующую команду можно использовать для вывода списка каталогов сокетов Windows, чтобы определить установленные поставщики услуг, а также семейство адресов, тип сокетов и протоколы, которые поддерживаются.

netsh winsock show catalog

Поддержка сокетов с типом SOCK_RAW не требуется, но поставщикам услуг рекомендуется поддерживать необработанные сокеты по мере возможности.

Заметки о сокетах IrDA

Помните о перечисленных ниже моментах.
  • Файл заголовка Af_irda.h должен быть явно включен.
  • Поддерживается только SOCK_STREAM ; Тип SOCK_DGRAM не поддерживается IrDA.
  • Параметр протокола всегда имеет значение 0 для IrDA.
Сокет для использования с семейством адресов 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 Windows Phone 8 и более поздних версий.

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
Header winsock2.h
Библиотека Ws2_32.lib
DLL Ws2_32.dll

См. также раздел

Параметры сокета IPPROTO_IP

Параметры сокета IPPROTO_IPV6

Надежное многоадресное программирование

WSASocket

Функции Winsock

Справочник по Winsock

Принять

bind

closesocket

connect;

getsockname

getsockopt

ioctlsocket

listen

Recv

recvfrom

select

send

Sendto

setsockopt

shutdown