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

Функция bind связывает локальный адрес с сокетом.

Синтаксис

int WSAAPI bind(
  [in] SOCKET         s,
  [in] const sockaddr *name,
  [in] int            namelen
);

Параметры

[in] s

Дескриптор, определяющий несвязанный сокет.

[in] name

Указатель на структуру sockaddr локального адреса для назначения связанному сокету .

[in] namelen

Длина (в байтах) значения, на которое указывает параметр name .

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

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

Код ошибки Значение
WSANOTINITIALISED
Примечание Перед использованием этой функции должен быть выполнен успешный вызов WSAStartup .
 
WSAENETDOWN
Произошел сбой сетевой подсистемы.
WSAEACCES
Предпринята попытка получить доступ к сокету способом, запрещенным его разрешениями на доступ.

Эта ошибка возвращается, если попытка nn связать сокет датаграммы с широковещательным адресом завершилась сбоем, так как параметр setsockopt SO_BROADCAST не включен.

WSAEADDRINUSE
обычно разрешено только одно использование каждого адреса сокета (протокол/сетевой адрес/порт).

Эта ошибка возвращается, если процесс на компьютере уже привязан к тому же полному адресу и сокет не помечен для разрешения повторного использования адреса с SO_REUSEADDR. Например, IP-адрес и порт, указанные в параметре name , уже привязаны к другому сокету, используемому другим приложением. Дополнительные сведения см. в разделе Параметр SO_REUSEADDR сокета в справочнике по параметрам сокета SOL_SOCKET, Использование SO_REUSEADDR и SO_EXCLUSIVEADDRUSE и SO_EXCLUSIVEADDRUSE.

WSAEADDRNOTAVAIL
Запрошенный адрес недопустим в контексте.

Эта ошибка возвращается, если указанный адрес, на который указывает параметр name , не является допустимым локальным IP-адресом на этом компьютере.

WSAEFAULT
Система обнаружила недопустимый адрес указателя при попытке использовать аргумент указателя в вызове.

Эта ошибка возвращается, если параметр name имеет значение NULL, параметр name или namelen не является допустимой частью адресного пространства пользователя, параметр namelen слишком мал, параметр name содержит неправильный формат адресов для связанного семейства адресов или первые два байта блока памяти, указанного именем, не соответствуют семейству адресов, связанному с дескриптором сокета.

WSAEINPROGRESS
Выполняется блокирующий вызов Windows Sockets 1.1 или поставщик услуг по-прежнему обрабатывает функцию обратного вызова.
WSAEINVAL
Указан недопустимый аргумент.

Эта ошибка возвращается из-за того , что сокет уже привязан к адресу.

WSAENOBUFS
Не удалось выполнить операцию с сокетом, так как в системе недостаточно места в буфере или из-за переполнения очереди.

Эта ошибка возвращается из-за недостаточного количества доступных буферов или слишком большого количества подключений.

WSAENOTSOCK
Предпринята попытка выполнить операцию с тем, что не является сокетом.

Эта ошибка возвращается, если дескриптор в параметре s не является сокетом.

Комментарии

Функция bind требуется в несвязанном сокете перед последующими вызовами функции прослушивания . Обычно он используется для привязки к сокетам, ориентированным на подключение (поток), или к сокетам без подключения (датаграмма). Функция bind также может использоваться для привязки к необработанному сокету (сокет был создан путем вызова функции сокета с параметром типа , равным SOCK_RAW). Функция bind также может использоваться в неподключаемом сокете перед последующими вызовами функций connect, ConnectEx, WSAConnect, WSAConnectByList или WSAConnectByName перед операциями отправки.

Когда сокет создается с помощью вызова функции сокета , он существует в пространстве имен (семействе адресов), но ему не назначено имя. Используйте функцию bind , чтобы установить локальную связь сокета, назначив локальное имя неименованного сокета.

Имя состоит из трех частей при использовании семейства адресов в Интернете:

  • Семейство адресов.
  • Адрес узла.
  • Номер порта, идентифицирующий приложение.

В Windows Sockets 2 параметр name не интерпретируется как указатель на структуру sockaddr . Это приводится таким образом для совместимости сокетов Windows 1.1. Поставщики услуг могут рассматривать его как указатель на блок памяти с размером namelen. Первые 2 байта в этом блоке (соответствующие sa_family элементу структуры sockaddr , элементу sin_family структуры sockaddr_in или члену sin6_family структуры sockaddr_in6 ) должны содержать семейство адресов, которое использовалось для создания сокета. В противном случае возникает ошибка WSAEFAULT.

Если приложению не важно, какой локальный адрес назначен, укажите значение константы INADDR_ANY для локального адреса IPv4 или значение константы , in6addr_any для локального адреса IPv6 в элементе sa_data параметра name . Это позволяет базовому поставщику услуг использовать любой соответствующий сетевой адрес, что потенциально упрощает программирование приложений при наличии многосетевых узлов (то есть узлов с несколькими сетевыми интерфейсами и адресами).

Для TCP/IP, если порт указан как нуль, поставщик служб назначает приложению уникальный порт из диапазона динамических клиентских портов. В Windows Vista и более поздних версиях динамический диапазон портов клиента находится в диапазоне от 49152 до 65535. Это отличие от Windows Server 2003 и более ранних версий, где динамический диапазон портов клиента был значением от 1025 до 5000. Максимальное значение для диапазона динамических портов клиента можно изменить, задав значение в следующем разделе реестра:

HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

Значение реестра MaxUserPort задает значение, используемое для максимального значения диапазона динамических клиентских портов. Чтобы этот параметр вступил в силу, необходимо перезагрузить компьютер.

В Windows Vista и более поздних версиях динамический диапазон портов клиента можно просматривать и изменять с помощью команд netsh . Динамический диапазон портов клиента можно задать по-разному для UDP и TCP, а также для IPv4 и IPv6. Дополнительные сведения см. в 929851 базы знаний.

Приложение может использовать getsockname после вызова привязки , чтобы узнать адрес и порт, назначенный сокету. Если интернет-адрес равен INADDR_ANY или in6addr_any, метод getsockname не может указывать адрес до подключения сокета, так как несколько адресов могут быть допустимыми, если узел является многосетевым. Привязка к определенному номеру порта, отличному от порта 0, не рекомендуется для клиентских приложений, так как существует опасность конфликта с другим сокетом, уже использующим этот номер порта на локальном компьютере.

Примечание При использовании привязки с параметром сокета SO_EXCLUSIVEADDRUSE или SO_REUSEADDR необходимо задать параметр сокета перед выполнением привязки , чтобы иметь какое-либо влияние. Дополнительные сведения см. в разделах SO_EXCLUSIVEADDRUSE и Использование SO_REUSEADDR и SO_EXCLUSIVEADDRUSE.

 

Для операций многоадресной рассылки предпочтительный метод — вызвать функцию привязки , чтобы связать сокет с локальным IP-адресом, а затем присоединиться к группе многоадресной рассылки. Хотя такой порядок операций не является обязательным, настоятельно рекомендуется. Поэтому многоадресное приложение сначала выбирает IPv4- или IPv6-адрес на локальном компьютере, IPv4-адрес с подстановочными знаками (INADDR_ANY) или IPv6-адрес с подстановочными знаками (in6addr_any). Затем многоадресное приложение вызовет функцию bind с этим адресом в элементе sa_data параметра name , чтобы связать локальный IP-адрес с сокетом. Если указан адрес с подстановочными знаками, Windows выберет локальный IP-адрес для использования. После завершения функции привязки приложение присоединится к интересующей группе многоадресной рассылки. Дополнительные сведения о присоединении к группе многоадресной рассылки см. в разделе Многоадресное программирование. Затем этот сокет можно использовать для получения многоадресных пакетов из группы многоадресной рассылки с помощью функций recv, recvfrom, WSARecvEx, WSARecvFrom или LPFN_WSARECVMSG (WSARecvMsg).

Функция привязки обычно не требуется для операций отправки в группу многоадресной рассылки. Функции sendto, WSASendMsg и WSASendTo неявно привязывают сокет к адресу с подстановочными знаками, если сокет еще не привязан. Функция bind требуется перед использованием функций send или WSASend , которые не выполняют неявную привязку и разрешены только для подключенных сокетов. Это означает, что сокет должен быть уже привязан для подключения. Функция bind может использоваться перед операциями отправки с помощью функций sendto, WSASendMsg или WSASendTo , если приложение хочет выбрать конкретный локальный IP-адрес на локальном компьютере с несколькими сетевыми интерфейсами и локальными IP-адресами. В противном случае неявная привязка к подстановочному адресу с помощью функций sendto, WSASendMsg или WSASendTo может привести к использованию другого локального IP-адреса для операций отправки.

Примечание При выполнении блокирующего вызова Winsock, например bind, Winsock может потребоваться дождаться сетевого события, прежде чем вызов сможет завершиться. В этой ситуации Winsock выполняет оповещенное ожидание, которое может быть прервано асинхронным вызовом процедуры (APC), запланированным в том же потоке. Выполнение другого блокирующего вызова Winsock внутри APC, который прервал текущий блокирующий вызов Winsock в том же потоке, приведет к неопределенному поведению и никогда не должен выполняться клиентами Winsock.
 

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

  • Файл заголовка Af_irda.h должен быть явно включен.
  • Локальные имена не предоставляются в IrDA. Таким образом, клиентские сокеты IrDA никогда не должны вызывать функцию bind перед функцией connect . Если сокет IrDA ранее был привязан к имени службы с помощью bind, функция connect завершится сбоем с SOCKET_ERROR.
  • Если имя службы имеет форму "LSAP-SELxxxx", где xxx — десятичное целое число в диапазоне от 1 до 127, адрес указывает на конкретный LSAP-SEL xxx, а не имя службы. Такие имена служб позволяют серверным приложениям принимать входящие подключения, направленные на определенный LSAP-SEL, без предварительного выполнения запроса имени службы ISA для получения связанного LSAP-SEL. Одним из примеров этого типа имени службы является устройство, отличное от Windows, которое не поддерживает IAS.

Windows Phone 8. Эта функция поддерживается для приложений Магазина Windows Phone на Windows Phone 8 и более поздних версиях.

Windows 8.1 и Windows Server 2012 R2. Эта функция поддерживается для приложений Магазина Windows на Windows 8.1, Windows Server 2012 R2 и более поздних версиях.

Примеры

В следующем примере показано использование функции привязки . Еще один пример, в котором используется функция bind, см. в разделе начало работы with Winsock.

#ifndef UNICODE
#define UNICODE
#endif

#define WIN32_LEAN_AND_MEAN

#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>

// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")

int main()
{

    // Declare some variables
    WSADATA wsaData;

    int iResult = 0;            // used to return function results

    // the listening socket to be created
    SOCKET ListenSocket = INVALID_SOCKET;

    // The socket address to be passed to bind
    sockaddr_in service;

    //----------------------
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != NO_ERROR) {
        wprintf(L"Error at WSAStartup()\n");
        return 1;
    }
    //----------------------
    // Create a SOCKET for listening for 
    // incoming connection requests
    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;
    }
    //----------------------
    // The sockaddr_in structure specifies the address family,
    // IP address, and port for the socket that is being bound.
    service.sin_family = AF_INET;
    service.sin_addr.s_addr = inet_addr("127.0.0.1");
    service.sin_port = htons(27015);

    //----------------------
    // Bind the socket.
    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;
    }
    else
        wprintf(L"bind returned success\n");

    WSACleanup();
    return 0;
}


Требования

   
Минимальная версия клиента Windows 8.1, Windows Vista [классические приложения | Приложения UWP]
Минимальная версия сервера Windows Server 2003 [классические приложения | Приложения UWP]
Целевая платформа Windows
Header winsock2.h (включая Winsock2.h)
Библиотека Ws2_32.lib
DLL Ws2_32.dll

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

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

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

SO_EXCLUSIVEADDRUSE

Необработанные сокеты TCP/IP

Использование SO_REUSEADDR и SO_EXCLUSIVEADDRUSE

WSACancelBlockingCall

Функции Winsock

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

connect;

getsockname

listen

setsockopt

sockaddr

Сокета