Compartir a través de


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
WSANOTINITIALISED
Nota Debe producirse una llamada WSAStartup correcta antes de usar esta función.
 
WSAENETDOWN
Error en el subsistema de red.
WSAEACCES
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.

WSAEADDRINUSE
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.

WSAEADDRNOTAVAIL
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.

WSAEFAULT
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.

WSAEINPROGRESS
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.
WSAEINVAL
Se ha proporcionado un argumento no válido.

Este error se devuelve del socket s ya está enlazado a una dirección.

WSAENOBUFS
Normalmente, WSAENOBUFS es una indicación de que no hay suficientes puertos efímeros para asignar para el enlace.
WSAENOTSOCK
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.

Nota Al usar el enlace con la opción de socket SO_EXCLUSIVEADDRUSE o SO_REUSEADDR, la opción de socket debe establecerse antes de ejecutar el enlace para que tenga algún efecto. Para obtener más información, consulte SO_EXCLUSIVEADDRUSE y Uso de SO_REUSEADDR y SO_EXCLUSIVEADDRUSE.

 

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.

Nota Al emitir una llamada de Winsock de bloqueo como bind, Winsock puede que tenga que esperar un evento de red antes de que se pueda completar la llamada. Winsock realiza una espera alertable en esta situación, que se puede interrumpir mediante una llamada de procedimiento asincrónica (APC) programada en el mismo subproceso. La emisión de otra llamada winsock de bloqueo dentro de un APC que interrumpió una llamada de Winsock de bloqueo en curso en el mismo subproceso provocará un comportamiento indefinido y los clientes winsock nunca deben intentarlo.
 

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

Programación de multidifusión

Opciones de socket de SOL_SOCKET

SO_EXCLUSIVEADDRUSE

Sockets sin formato TCP/IP

Uso de SO_REUSEADDR y SO_EXCLUSIVEADDRUSE

WSACancelBlockingCall

Funciones winsock

Referencia de Winsock

connect

getsockname

listen

setsockopt

sockaddr

socket