función bind (winsock.h)
La función bind asocia una dirección local a un socket.
Sintaxis
int bind(
[in] SOCKET s,
const sockaddr *addr,
[in] int namelen
);
Parámetros
[in] s
Descriptor que identifica un socket independiente.
addr
Puntero a una estructura sockaddr de la dirección local que se va a asignar al socket enlazado.
[in] namelen
Longitud, en bytes, del valor al que apunta addr.
Valor devuelto
Si no se produce ningún error, bind devuelve cero. De lo contrario, devuelve SOCKET_ERROR y se puede recuperar un código de error específico mediante una llamada a WSAGetLastError.
Código de error | Significado |
---|---|
Nota Debe producirse una llamada WSAStartup correcta antes de usar esta función.
|
|
Error en el subsistema de red. | |
Se ha intentado obtener acceso a un socket de una manera no permitida por los permisos de acceso.
Este error se devuelve si nn intenta enlazar un socket de datagrama a la dirección de difusión no se pudo realizar porque la opción setsockopt SO_BROADCAST no está habilitada. |
|
Only one usage of each socket address (protocol/network address/port) is normally permitted.
Este error se devuelve si un proceso del equipo ya está enlazado a la misma dirección completa y el socket no se ha marcado para permitir la reutilización de direcciones con SO_REUSEADDR. Por ejemplo, la dirección IP y el puerto especificados en el parámetro name ya están enlazados a otro socket que usa otra aplicación. Para obtener más información, consulte la opción SO_REUSEADDR socket en la referencia de opciones de socket de SOL_SOCKET , Uso de SO_REUSEADDR y SO_EXCLUSIVEADDRUSE y SO_EXCLUSIVEADDRUSE. |
|
La dirección solicitada no es válida en su contexto.
Este error se devuelve si la dirección especificada a la que apunta el parámetro name no es una dirección IP local válida en este equipo. |
|
El sistema ha detectado una dirección de puntero no válida al intentar usar un argumento de puntero en una llamada.
Este error se devuelve si el parámetro name es NULL, el parámetro name o namelen no es una parte válida del espacio de direcciones de usuario, el parámetro namelen es demasiado pequeño, el parámetro name contiene un formato de dirección incorrecto para la familia de direcciones asociada o los dos primeros bytes del bloque de memoria especificado por name no coinciden con la familia de direcciones asociada con los descriptores de socket. |
|
Una llamada de Bloqueo de Windows Sockets 1.1 está en curso o el proveedor de servicios sigue procesando una función de devolución de llamada. | |
Se ha proporcionado un argumento no válido.
Este error se devuelve del socket s ya está enlazado a una dirección. |
|
Normalmente, WSAENOBUFS es una indicación de que no hay suficientes puertos efímeros para asignar para el enlace. | |
Se ha intentado realizar una operación en algo que no es un socket.
Este error se devuelve si el descriptor del parámetro s no es un socket. |
Comentarios
La función bind es necesaria en un socket no conectado antes de las llamadas posteriores a la función de escucha . Normalmente se usa para enlazar a sockets orientados a la conexión (secuencia) o a sockets sin conexión (datagramas). La función bind también se puede usar para enlazar a un socket sin formato (el socket se creó llamando a la función socket con el parámetro de tipo establecido en SOCK_RAW). La función bind también se puede usar en un socket no conectado antes de las llamadas posteriores a las funciones connect, ConnectEx, WSAConnect, WSAConnectByList o WSAConnectByName antes de enviar operaciones.
Cuando se crea un socket con una llamada a la función de socket , existe en un espacio de nombres (familia de direcciones), pero no tiene ningún nombre asignado. Use la función bind para establecer la asociación local del socket mediante la asignación de un nombre local a un socket sin nombre.
Un nombre consta de tres partes al usar la familia de direcciones de Internet:
- Familia de direcciones.
- Una dirección de host.
- Número de puerto que identifica la aplicación.
En Windows Sockets 2, el parámetro name no se interpreta estrictamente como puntero a una estructura sockaddr . Se convierte de esta manera para la compatibilidad con Windows Sockets 1.1. Los proveedores de servicios son libres de considerarlo como puntero a un bloque de memoria de tamaño namelen. Los primeros 2 bytes de este bloque (correspondientes al miembro sa_family de la estructura sockaddr , el miembro sin_family de la estructura sockaddr_in o el miembro sin6_family de la estructura sockaddr_in6 ) deben contener la familia de direcciones que se usó para crear el socket. De lo contrario, se produce un error WSAEFAULT.
Si una aplicación no importa qué dirección local se asigna, especifique el valor constante INADDR_ANY para una dirección local IPv4 o el valor constante in6addr_any para una dirección local IPv6 en el miembro sa_data miembro del parámetro name . Esto permite al proveedor de servicios subyacente usar cualquier dirección de red adecuada, lo que puede simplificar la programación de aplicaciones en presencia de hosts de host múltiples (es decir, hosts que tienen más de una interfaz de red y una dirección).
Para TCP/IP, si el puerto se especifica como cero, el proveedor de servicios asigna un puerto único a la aplicación desde el intervalo de puertos de cliente dinámico. En Windows Vista y versiones posteriores, el intervalo de puertos de cliente dinámico es un valor entre 49152 y 65535. Se trata de un cambio de Windows Server 2003 y versiones anteriores donde el intervalo de puertos de cliente dinámico era un valor entre 1025 y 5000. El valor máximo del intervalo de puertos dinámicos de cliente se puede cambiar estableciendo un valor en la siguiente clave del Registro:
HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
El valor del Registro MaxUserPort establece el valor que se va a usar para el valor máximo del intervalo de puertos de cliente dinámico. Debe reiniciar el equipo para que esta configuración surta efecto.
En Windows Vista y versiones posteriores, el intervalo de puertos de cliente dinámico se puede ver y cambiar mediante comandos netsh . El intervalo de puertos de cliente dinámico se puede establecer de forma diferente para UDP y TCP y también para IPv4 e IPv6. Para obtener más información, consulte KB 929851.
La aplicación puede usar getsockname después de llamar al enlace para conocer la dirección y el puerto que se ha asignado al socket. Si la dirección de Internet es igual a INADDR_ANY o in6addr_any, getsockname no puede proporcionar necesariamente la dirección hasta que el socket esté conectado, ya que varias direcciones pueden ser válidas si el host es de host múltiple. No se recomienda el enlace a un número de puerto específico distinto del puerto 0 para las aplicaciones cliente, ya que existe un peligro de conflicto con otro socket que ya usa ese número de puerto en el equipo local.
En el caso de las operaciones de multidifusión, el método preferido es llamar a la función bind para asociar un socket a una dirección IP local y, a continuación, unirse al grupo de multidifusión. Aunque este orden de operaciones no es obligatorio, se recomienda encarecidamente. Por lo tanto, una aplicación de multidifusión seleccionaría primero una dirección IPv4 o IPv6 en el equipo local, la dirección IPv4 con caracteres comodín (INADDR_ANY) o la dirección IPv6 comodín (in6addr_any). A continuación, la aplicación de multidifusión llamaría a la función bind con esta dirección en en el miembro sa_data del parámetro name para asociar la dirección IP local con el socket. Si se especificó una dirección comodín, Windows seleccionará la dirección IP local que se usará. Una vez completada la función de enlace , una aplicación se uniría al grupo de multidifusión de interés. Para obtener más información sobre cómo unirse a un grupo de multidifusión, consulte la sección programación de multidifusión. Después, este socket se puede usar para recibir paquetes de multidifusión del grupo de multidifusión mediante las funciones recv, recvfrom, WSARecv, WSARecvEx, WSARecvFrom o LPFN_WSARECVMSG (WSARecvMsg).
Normalmente, la función bind no es necesaria para las operaciones de envío a un grupo de multidifusión. Las funciones sendto,WSASendMsg y WSASendTo enlazan implícitamente el socket a la dirección de comodín si el socket aún no está enlazado. La función bind es necesaria antes del uso de las funciones send o WSASend que no realizan un enlace implícito y solo se permiten en sockets conectados, lo que significa que el socket ya debe estar enlazado para que esté conectado. La función de enlace se puede usar antes de enviar operaciones mediante las funciones sendto,WSASendMsg o WSASendTo si una aplicación quería seleccionar una dirección IP local específica en un equipo local con varias interfaces de red y direcciones IP locales. De lo contrario, un enlace implícito a la dirección comodín mediante las funciones sendto,WSASendMsg o WSASendTo podría dar lugar a que se use una dirección IP local diferente para las operaciones de envío.
Notas para sockets IrDA
- El archivo de encabezado Af_irda.h debe incluirse explícitamente.
- Los nombres locales no se exponen en IrDA. Por lo tanto, los sockets de cliente irDA nunca deben llamar a la función bind antes de la función connect . Si el socket IrDA se ha enlazado previamente a un nombre de servicio mediante bind, se producirá un error en la función connect con SOCKET_ERROR.
- Si el nombre del servicio tiene el formato "LSAP-SELxxx", donde xxx es un entero decimal en el intervalo 1-127, la dirección indica un LSAP-SEL xxx específico en lugar de un nombre de servicio. Los nombres de servicio, como estos, permiten a las aplicaciones de servidor aceptar conexiones entrantes dirigidas a un LSAP-SEL específico, sin realizar primero una consulta de nombre de servicio ISA para obtener el LSAP-SEL asociado. Un ejemplo de este tipo de nombre de servicio es un dispositivo que no es Windows que no admite IAS.
Windows Phone 8: esta función es compatible con las aplicaciones de Windows Phone Store en Windows Phone 8 y versiones posteriores.
Windows 8.1 y Windows Server 2012 R2: esta función es compatible con las aplicaciones de la Tienda Windows en Windows 8.1, Windows Server 2012 R2 y versiones posteriores.
Ejemplos
En el ejemplo siguiente se muestra el uso de la función bind . Para obtener otro ejemplo que use la función bind, consulte Introducción 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;
}
Requisitos
Requisito | Value |
---|---|
Cliente mínimo compatible | Windows 8.1, Windows Vista [aplicaciones de escritorio | Aplicaciones para UWP] |
Servidor mínimo compatible | Windows Server 2003 [aplicaciones de escritorio | aplicaciones para UWP] |
Plataforma de destino | Windows |
Encabezado | winsock.h (incluya Winsock2.h) |
Library | Ws2_32.lib |
Archivo DLL | Ws2_32.dll |
Consulte también
Opciones de socket de SOL_SOCKET