Функция bind (winsock.h)
Функция bind связывает локальный адрес с сокетом.
Синтаксис
int bind(
[in] SOCKET s,
const sockaddr *addr,
[in] int namelen
);
Параметры
[in] s
Дескриптор, определяющий несвязанный сокет.
addr
Указатель на структуру sockaddr локального адреса, назначаемого связанному сокету.
[in] namelen
Длина (в байтах) значения, на которое указывает addr.
Возвращаемое значение
Если ошибка не возникает, функция привязки возвращает ноль. В противном случае он возвращает SOCKET_ERROR, и конкретный код ошибки можно получить, вызвав WSAGetLastError.
Код ошибки | Значение |
---|---|
Примечание Перед использованием этой функции должен произойти успешный вызов WSAStartup .
|
|
Произошел сбой сетевой подсистемы. | |
Предпринята попытка доступа к сокету способом, запрещенным его разрешениями на доступ.
Эта ошибка возвращается, если попытка nn привязать сокет датаграммы к широковещательным адресам завершилась сбоем, так как параметр setsockopt SO_BROADCAST не включен. |
|
обычно разрешено только одно использование каждого адреса сокета (протокол/сетевой адрес/порт).
Эта ошибка возвращается, если процесс на компьютере уже привязан к тому же полному адресу и сокет не помечен, чтобы разрешить повторное использование адреса с SO_REUSEADDR. Например, IP-адрес и порт, указанные в параметре name , уже привязаны к другому сокету, используемому другим приложением. Дополнительные сведения см. в разделе Параметр сокета SO_REUSEADDR в справочнике по параметрам сокета SOL_SOCKET, Использование SO_REUSEADDR и SO_EXCLUSIVEADDRUSE и SO_EXCLUSIVEADDRUSE. |
|
Запрошенный адрес недопустим в контексте.
Эта ошибка возвращается, если указанный адрес, на который указывает параметр name , не является допустимым локальным IP-адресом на этом компьютере. |
|
Система обнаружила недопустимый адрес указателя при попытке использовать аргумент указателя в вызове.
Эта ошибка возвращается, если параметр name имеет значение NULL, параметр name или namelen не является допустимой частью адресного пространства пользователя, параметр namelen слишком мал, параметр name содержит неправильный формат адресов для связанного семейства адресов или первые два байта блока памяти, указанного именем, не соответствуют семейству адресов, связанному с дескрипторов сокетов. |
|
Выполняется блокирующий вызов Windows Sockets 1.1 или поставщик услуг по-прежнему обрабатывает функцию обратного вызова. | |
Указан недопустимый аргумент.
Эта ошибка возвращается из-за того , что сокет уже привязан к адресу. |
|
Как правило, WSAENOBUFS указывает на то, что для привязки недостаточно временных портов. | |
Предпринята попытка выполнения операции с тем, что не является сокетом.
Эта ошибка возвращается, если дескриптор в параметре 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, не рекомендуется для клиентских приложений, так как существует опасность конфликта с другим сокетом, уже использующим этот номер порта на локальном компьютере.
Для операций многоадресной рассылки предпочтительным методом является вызов функции привязки , чтобы связать сокет с локальным IP-адресом, а затем присоединиться к группе многоадресной рассылки. Хотя такой порядок операций не является обязательным, настоятельно рекомендуется. Поэтому приложение многоадресной рассылки сначала выбирает IPv4- или IPv6-адрес на локальном компьютере, IPv4-адрес с подстановочными знаками (INADDR_ANY) или IPv6-адрес с подстановочными знаками (in6addr_any). Затем многоадресное приложение вызовет функцию bind с этим адресом в элементе sa_data параметра name , чтобы связать локальный IP-адрес с сокетом. Если указан адрес с подстановочными знаками, Windows выберет локальный IP-адрес для использования. После завершения функции привязки приложение присоединится к интересующей группе многоадресной рассылки. Дополнительные сведения о присоединении к группе многоадресной рассылки см. в разделе Многоадресное программирование. Затем этот сокет можно использовать для получения пакетов многоадресной рассылки из группы многоадресной рассылки с помощью функций recv, recvfrom, WSARecvEx, WSARecvFrom или LPFN_WSARECVMSG (WSARecvMsg).
Функция bind обычно не требуется для операций отправки в группу многоадресной рассылки. Функции sendto, WSASendMsg и WSASendTo неявно привязывают сокет к адресу с подстановочными знаками, если сокет еще не привязан. Функция bind требуется перед использованием функций send или WSASend , которые не выполняют неявную привязку и разрешены только для подключенных сокетов. Это означает, что сокет должен быть уже привязан для подключения. Функция bind может использоваться перед операциями отправки с помощью функций sendto, WSASendMsg или WSASendTo , если приложению требуется выбрать конкретный локальный IP-адрес на локальном компьютере с несколькими сетевыми интерфейсами и локальными IP-адресами. В противном случае неявная привязка к подстановочному адресу с помощью функций sendto, WSASendMsg или WSASendTo может привести к использованию другого локального IP-адреса для операций отправки.
Примечания для сокетов IrDA
- Файл заголовка Af_irda.h должен быть явно включен.
- Локальные имена не предоставляются в IrDA. Поэтому клиентские сокеты IrDA никогда не должны вызывать функцию bind перед функцией connect . Если сокет IrDA ранее был привязан к имени службы с помощью привязки, функция 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 . Другой пример, в котором используется функция bind, см. в разделе начало работы с 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 | winsock.h (включая Winsock2.h) |
Библиотека | Ws2_32.lib |
DLL | Ws2_32.dll |
См. также раздел
Многоадресное программирование