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