Función WSAAccept (winsock2.h)
La función WSAAccept acepta condicionalmente una conexión basada en el valor devuelto de una función de condición, proporciona especificaciones de flujo de servicio de calidad y permite la transferencia de datos de conexión.
Sintaxis
SOCKET WSAAPI WSAAccept(
[in] SOCKET s,
[out] sockaddr *addr,
[in, out] LPINT addrlen,
[in] LPCONDITIONPROC lpfnCondition,
[in] DWORD_PTR dwCallbackData
);
Parámetros
[in] s
Descriptor que identifica un socket que está escuchando conexiones después de una llamada a la función de escucha de
[out] addr
Puntero opcional a una estructura de sockaddr 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 establecida cuando se creó el socket.
[in, out] addrlen
Puntero opcional a un entero que contiene la longitud del estructura sockaddr a la que apunta el parámetro addr, en bytes.
[in] lpfnCondition
Dirección de una función de condición opcional especificada por la aplicación que tomará una decisión de aceptación o rechazo basada en la información del autor de la llamada que se pasa como parámetros y, opcionalmente, cree o una un grupo de sockets asignando un valor adecuado al parámetro de resultado g de esta función. Si este parámetro es NULL, no se llama a ninguna función condition.
[in] dwCallbackData
Los datos de devolución de llamada pasados a la función de condición especificada por la aplicación como el valor del parámetro dwCallbackData pasado a la función de condición. Este parámetro solo es aplicable si el parámetro lpfnCondition
Valor devuelto
Si no se produce ningún error, WSAAccept devuelve un valor de tipo SOCKET que es un descriptor para el socket aceptado. De lo contrario, se devuelve un valor de INVALID_SOCKET y se puede recuperar un código de error específico llamando a WSAGetLastError.
El entero al que hace referencia addrlen inicialmente contiene la cantidad de espacio al que apunta addr. Al devolver, contendrá la longitud real en bytes de la dirección devuelta.
Código de error | Significado |
---|---|
Se intentó acceder a un socket de forma prohibida por sus permisos de acceso. Este error se devuelve si la solicitud de conexión que se ofreció ha agotado el tiempo de espera o se ha retirado. | |
No se pudo establecer ninguna conexión porque la máquina de destino la rechazó activamente. Este error se devuelve si la solicitud de conexión se rechazó forzadamente como se indica en el valor devuelto de la función de condición (CF_REJECT). | |
El host remoto cerró forzadamente una conexión existente. Este error se devuelve de una conexión entrante indicada, pero posteriormente lo finalizó el mismo nivel remoto antes de aceptar la llamada. | |
El sistema detectó una dirección de puntero no válida al intentar usar un argumento de puntero en una llamada. Este error se devuelve del parámetro addrlen |
|
Una operación de bloqueo se interrumpió mediante una llamada a WSACancelBlockingCall. Este error se devuelve si se canceló una llamada de Bloqueo de Windows Sockets 1.1 a través de WSACancelBlockingCall. | |
Actualmente se está ejecutando una operación de bloqueo. Este error se devuelve si una llamada a Windows Sockets 1.1 está en curso. | |
Se proporcionó un argumento no válido. Este error se devuelve si de escucha no se invocó antes de WSAAccept, el valor devuelto de la función condition no es válido o si el socket especificado está en un estado no válido. | |
Demasiados sockets abiertos. Este error se devuelve si la cola no está vacía tras la entrada a WSAAccept y no hay descriptores de socket disponibles. | |
Una operación de socket encontró una red inactiva. Este error se devuelve si se ha producido un error en el subsistema de red. | |
No se pudo realizar una operación en un socket porque el sistema no tenía suficiente espacio en búfer o porque una cola estaba llena. Este error se devuelve si no hay ningún espacio de búfer disponible. | |
Se intentó realizar una operación en algo que no es un socket. Este error se devuelve si el descriptor de socket pasado en el parámetro de |
|
La familia de protocolos no se ha configurado en el sistema o no existe ninguna implementación para ella. Este error se devuelve si el socket al que se hace referencia no es un tipo que admite el servicio orientado a la conexión. | |
No se pudo completar inmediatamente una operación de socket sin bloqueo. Este error se devuelve si el socket está marcado como no desbloqueado y no hay conexiones que se acepten. | |
No se ha llamado a la aplicación WSAStartupo error WSAStartup. Este error se devuelve de una llamada correcta a la WSAStartup función dit no se produce antes de usar esta función. | |
Normalmente se trata de un error temporal durante la resolución del nombre de host y significa que el servidor local no recibió una respuesta de un servidor autoritativo. Este error se devuelve si la aceptación de la solicitud de conexión se aplaza como se indica en el valor devuelto de la función de condición (CF_DEFER). |
Observaciones
La función WSAAccept extrae la primera conexión en la cola de conexiones pendientes en el socket sy la comprueba con la función condition, siempre que se especifique la función condition (es decir, no NULL). Si la función condition devuelve CF_ACCEPT, WSAAccept crea un nuevo socket. El socket recién creado tiene las mismas propiedades que el de socket
Un socket en modo predeterminado (bloqueo) se bloqueará hasta que una conexión esté presente cuando una aplicación llame a WSAAccept y no haya conexiones pendientes en la cola.
Se produce un error en un socket en modo de no bloqueo (bloqueo) con el error WSAEWOULDBLOCK cuando una aplicación llama a WSAAccept y no hay ninguna conexión pendiente en la cola. Después de WSAAccept se realiza correctamente y 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 parámetro addr 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
Un prototipo de la función condition se define en el archivo de encabezado Winsock2.h
como el LPCONDITIONPROC, como se indica a continuación.
int CALLBACK
ConditionFunc(
IN LPWSABUF lpCallerId,
IN LPWSABUF lpCallerData,
IN OUT LPQOS lpSQOS,
IN OUT LPQOS lpGQOS,
IN LPWSABUF lpCalleeId,
IN LPWSABUF lpCalleeData,
OUT GROUP FAR * g,
IN DWORD_PTR dwCallbackData
);
El ConditionFunc de
El parámetro lpCallerId apunta a una estructura WSABUF que contiene la dirección de la entidad de conexión, donde su parámetro len es la longitud del búfer en bytes y su parámetro buf es un puntero al búfer. El lpCallerData es un parámetro de valor que contiene los datos de usuario. La información de estos parámetros se envía junto con la solicitud de conexión. Si no hay ningún dato de identificación o autor de llamada disponible, los parámetros correspondientes serán NULL. Muchos protocolos de red no admiten datos del autor de llamada en tiempo de conexión. Se espera que la mayoría de los protocolos de red convencionales admitan la información del identificador de llamada en el momento de la solicitud de conexión. La parte buf del WSABUF apunta a por lpCallerId apunta a un sockaddr. La estructura
El parámetro
El parámetro lpGQOS está reservado y debe ser null. (reservado para uso futuro con grupos de sockets) hace referencia a la estructura FLOWSPEC para el grupo de sockets que el autor de la llamada va a crear, uno para cada dirección, seguido de cualquier parámetro adicional específico del proveedor. Un valor de NULL para lpGQOS indica que no hay calidad de servicio especificada por el autor de la llamada. Se puede devolver la información de calidad del servicio si se va a producir la negociación.
El lpCalleeId es un parámetro que contiene la dirección local de la entidad conectada. El buf parte del WSABUF al que apunta lpCalleeId apunta a una estructura de . La estructura
El lpCalleeData es un parámetro de resultado utilizado por la función condition para devolver los datos de usuario a la entidad de conexión. El lpCalleeData-> inicialmente contiene la longitud del búfer asignado por el proveedor de servicios y apuntado por lpCalleeData->buf. Un valor de cero significa que no se admite la transferencia de datos de usuario al autor de la llamada. La función condition debe copiar hasta lpCalleeData->len bytes de datos en lpCalleeData->bufy, a continuación, actualizar lpCalleeData->len para indicar el número real de bytes transferidos. Si no hay datos de usuario que se devuelvan al autor de la llamada, la función condition debe establecer lpCalleeData->len en cero. El formato de todos los datos de dirección y usuario es específico de la familia de direcciones a la que pertenece el socket.
El parámetro g se asigna dentro de la función condition para indicar cualquiera de las acciones siguientes:
- Si g es un identificador de grupo de sockets existente, agregue s a este grupo, siempre que se cumplan todos los requisitos establecidos por este grupo.
- Si g = SG_UNCONSTRAINED_GROUP, cree un grupo de sockets sin restricciones y tenga s como primer miembro.
- Si g = SG_CONSTRAINED_GROUP, cree un grupo de sockets restringido y tenga s como primer miembro.
- Si g = cero, no se realiza ninguna operación de grupo.
El valor del parámetro
código de ejemplo de
En el ejemplo siguiente se muestra el uso de la función#include <winsock2.h>
#include <stdio.h>
#include <windows.h>
/* Define an example conditional function that depends on the pQos field */
int CALLBACK ConditionAcceptFunc(
LPWSABUF lpCallerId,
LPWSABUF lpCallerData,
LPQOS pQos,
LPQOS lpGQOS,
LPWSABUF lpCalleeId,
LPWSABUF lpCalleeData,
GROUP FAR * g,
DWORD_PTR dwCallbackData
)
{
if (pQos != NULL) {
RtlZeroMemory(pQos, sizeof(QOS));
return CF_ACCEPT;
} else
return CF_REJECT;
}
int main() {
/* Declare and initialize variables */
WSADATA wsaData;
SOCKET ListenSocket, AcceptSocket;
struct sockaddr_in saClient;
int iClientSize = sizeof(saClient);
u_short port = 27015;
char* ip;
sockaddr_in service;
int error;
/* Initialize Winsock */
error = WSAStartup(MAKEWORD(2,2), &wsaData);
if (error) {
printf("WSAStartup() failed with error: %d\n", error);
return 1;
}
/* Create a TCP listening socket */
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ListenSocket == INVALID_SOCKET) {
printf("socket() failed with error: %d\n", WSAGetLastError() );
WSACleanup();
return 1;
}
/*-----------------------------------------
* Set up the sock addr structure that the listening socket
* will be bound to. In this case, the structure holds the
* local IP address and the port specified. */
service.sin_family = AF_INET;
service.sin_port = htons(port);
hostent* thisHost;
thisHost = gethostbyname("");
ip = inet_ntoa (*(struct in_addr *)*thisHost->h_addr_list);
service.sin_addr.s_addr = inet_addr(ip);
/*-----------------------------------------
* Bind the listening socket to the IP address.
* and port number specified by the sockaddr structure. */
error = bind(ListenSocket, (SOCKADDR *) &service, sizeof(SOCKADDR));
if (error == SOCKET_ERROR) {
printf("bind() failed with error: %d\n", WSAGetLastError() );
closesocket(ListenSocket);
WSACleanup();
return 1;
}
/* Make the socket listen for incoming connection requests */
error = listen(ListenSocket, 1);
if (error == SOCKET_ERROR) {
printf("listen() failed with error: %d\n", WSAGetLastError() );
closesocket(ListenSocket);
WSACleanup();
return 1;
}
printf("Listening...\n");
/*-----------------------------------------
* Accept an incoming connection request on the
* listening socket and transfer control to the
* accepting socket. */
AcceptSocket = WSAAccept(ListenSocket, (SOCKADDR*) &saClient, &iClientSize,
&ConditionAcceptFunc, NULL);
/* Now do some work with the AcceptSocket
* At this point, the application could
* handle data transfer on the socket, or other socket
* functionality.*/
/* Then clean up and quit */
closesocket(AcceptSocket);
closesocket(ListenSocket);
WSACleanup();
return 0;
}
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.
Requisitos
Requisito | Valor |
---|---|
cliente mínimo admitido | Windows 8.1, Windows Vista [aplicaciones de escritorio | Aplicaciones para UWP] |
servidor mínimo admitido | Windows Server 2003 [aplicaciones de escritorio | Aplicaciones para UWP] |
de la plataforma de destino de |
Windows |
encabezado de |
winsock2.h |
biblioteca de |
Ws2_32.lib |
DLL de |
Ws2_32.dll |
Consulte también
de socket de