Compartir a través de


función accept (winsock2.h)

La función accept permite un intento de conexión entrante en un socket.

Sintaxis

SOCKET WSAAPI accept(
  [in]      SOCKET   s,
  [out]     sockaddr *addr,
  [in, out] int      *addrlen
);

Parámetros

[in] s

Descriptor que identifica un socket que se ha colocado en un estado de escucha con la función de escucha . La conexión se realiza realmente con el socket devuelto por accept.

[out] addr

Puntero opcional a un búfer que recibe la dirección de la entidad de conexión, como se conoce en la capa de comunicaciones. El formato exacto del parámetro addr viene determinado por la familia de direcciones que se estableció cuando se creó el socket de la estructura sockaddr .

[in, out] addrlen

Puntero opcional a un entero que contiene la longitud de la estructura a la que apunta el parámetro addr .

Valor devuelto

Si no se produce ningún error, accept devuelve un valor de tipo SOCKET que es un descriptor para el nuevo socket. Este valor devuelto es un identificador para el socket en el que se realiza la conexión real.

De lo contrario, se devuelve un valor de INVALID_SOCKET y se puede recuperar un código de error específico mediante una llamada a WSAGetLastError.

El entero al que hace referencia addrlen inicialmente contiene la cantidad de espacio al que apunta el addr. Al devolver, contendrá la longitud real en bytes de la dirección devuelta.

Código de error Significado
WSANOTINITIALISED
Debe producirse una llamada WSAStartup correcta antes de usar esta función.
WSAECONNRESET
Se indicó una conexión entrante, pero posteriormente el par remoto finalizó antes de aceptar la llamada.
WSAEFAULT
El parámetro addrlen es demasiado pequeño o el agregador no es una parte válida del espacio de direcciones del usuario.
WSAEINTR
Se canceló una llamada de Bloqueo de Windows Sockets 1.1 a través de WSACancelBlockingCall.
WSAEINVAL
La función de escucha no se invocó antes de aceptar.
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.
WSAEMFILE
La cola no está vacía tras la entrada para aceptar y no hay descriptores disponibles.
WSAENETDOWN
Error en el subsistema de red.
WSAENOBUFS
No hay espacio disponible en el búfer.
WSAENOTSOCK
El descriptor no es un socket.
WSAEOPNOTSUPP
El socket al que se hace referencia no es un tipo que admite el servicio orientado a la conexión.
WSAEWOULDBLOCK
El socket está marcado como de no bloqueo y no hay conexiones presentes que aceptar.

Comentarios

La función accept extrae la primera conexión de la cola de conexiones pendientes en los sockets. A continuación, crea y devuelve un identificador al nuevo socket. El socket recién creado es el socket que controlará la conexión real; tiene las mismas propiedades que los sockets, incluidos los eventos asincrónicos registrados con las funciones WSAAsyncSelect o WSAEventSelect .

La función accept puede bloquear al autor de la llamada hasta que haya una conexión si no hay ninguna conexión pendiente en la cola y el socket se marca como bloqueo. Si el socket está marcado como sin bloqueo y no hay conexiones pendientes en la cola, accept devuelve un error como se describe en lo siguiente. Una vez completada correctamente la aceptación , se devuelve un nuevo identificador de socket, el socket aceptado no se puede usar para aceptar más conexiones. El socket original permanece abierto y escucha las nuevas solicitudes de conexión.

El agregador de parámetros es un parámetro de resultado que se rellena con la dirección de la entidad de conexión, como se conoce en la capa de comunicaciones. El formato exacto del parámetro addr viene determinado por la familia de direcciones en la que se está produciendo la comunicación. El addrlen es un parámetro value-result; debe contener inicialmente la cantidad de espacio al que apunta el agregador; al devolver, contendrá la longitud real (en bytes) de la dirección devuelta.

La función accept se usa con tipos de socket orientados a la conexión, como SOCK_STREAM. Si addr o addrlen son iguales a NULL, no se devuelve información sobre la dirección remota del socket aceptado.

Nota Al emitir una llamada de Winsock de bloqueo como accept, 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.
 

Código de ejemplo

En el ejemplo siguiente se muestra el uso de la función accept .
#ifndef UNICODE
#define UNICODE
#endif

#include <winsock2.h>
#include <WS2tcpip.h>
#include <stdio.h>
#include <windows.h>

// Need to link with Ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")

int wmain(void)
{

    //----------------------
    // Initialize Winsock.
    WSADATA wsaData;
    int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != NO_ERROR) {
        wprintf(L"WSAStartup failed with error: %ld\n", iResult);
        return 1;
    }
    //----------------------
    // Create a SOCKET for listening for
    // incoming connection requests.
    SOCKET ListenSocket;
    ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (ListenSocket == INVALID_SOCKET) {
        wprintf(L"socket failed with error: %ld\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }
    //----------------------
    // The sockaddr_in structure specifies the address family,
    // IP address, and port for the socket that is being bound.
    sockaddr_in service;
    service.sin_family = AF_INET;
    service.sin_port = htons(27015);
    inet_pton(AF_INET, "127.0.0.1", &service.sin_addr);

    if (bind(ListenSocket,
             (SOCKADDR *) & service, sizeof (service)) == SOCKET_ERROR) {
        wprintf(L"bind failed with error: %ld\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }
    //----------------------
    // Listen for incoming connection requests.
    // on the created socket
    if (listen(ListenSocket, 1) == SOCKET_ERROR) {
        wprintf(L"listen failed with error: %ld\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }
    //----------------------
    // Create a SOCKET for accepting incoming requests.
    SOCKET AcceptSocket;
    wprintf(L"Waiting for client to connect...\n");

    //----------------------
    // Accept the connection.
    AcceptSocket = accept(ListenSocket, NULL, NULL);
    if (AcceptSocket == INVALID_SOCKET) {
        wprintf(L"accept failed with error: %ld\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    } else
        wprintf(L"Client connected.\n");

    // No longer need server socket
    closesocket(ListenSocket);

    WSACleanup();
    return 0;
}


Para obtener otro ejemplo que usa la función accept, vea Introducción With Winsock.

Notas para ATM

Los siguientes son problemas importantes asociados con la configuración de conexión y se deben tener en cuenta al usar el modo de transferencia asincrónica (ATM) con Windows Sockets 2:

  • Las funciones accept y WSAAccept no establecen necesariamente los parámetros de longitud de dirección y dirección remota. Por lo tanto, al usar ATM, el autor de la llamada debe usar la función WSAAccept y colocar ATM_CALLING_PARTY_NUMBER_IE en el miembro ProviderSpecific de la estructura QoS , que se incluye en el parámetro lpSQOS de la función de devolución de llamada utilizada de acuerdo con WSAAccept.
  • Al usar la función accept , tenga en cuenta que la función puede devolver antes de que el establecimiento de la conexión haya recorrido toda la distancia entre el remitente y el receptor. Esto se debe a que la función accept devuelve tan pronto como recibe un mensaje CONNECT ACK; en ATM, el siguiente modificador de la ruta de acceso devuelve un mensaje CONNECT ACK en cuanto se procesa un mensaje CONNECT (en lugar del nodo final al que se envía la conexión). Por lo tanto, las aplicaciones deben darse cuenta de que si los datos se envían inmediatamente después de la recepción de un mensaje CONNECT ACK, es posible la pérdida de datos, ya que es posible que la conexión no se haya establecido de forma completa entre el remitente y el receptor.

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.

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 winsock2.h
Library Ws2_32.lib
Archivo DLL Ws2_32.dll

Consulte también

WSAAccept

WSAAsyncSelect

Funciones winsock

Referencia de Winsock

bind

connect

listen

select

sockaddr

socket