Função WSAAccept (winsock2.h)
A função WSAAccept aceita condicionalmente uma conexão com base no valor retornado de uma função de condição, fornece qualidade das especificações de fluxo de serviço e permite a transferência de dados de conexão.
Sintaxe
SOCKET WSAAPI WSAAccept(
[in] SOCKET s,
[out] sockaddr *addr,
[in, out] LPINT addrlen,
[in] LPCONDITIONPROC lpfnCondition,
[in] DWORD_PTR dwCallbackData
);
Parâmetros
[in] s
Um descritor que identifica um soquete que está escutando conexões após uma chamada para o escuta função.
[out] addr
Um ponteiro opcional para uma estrutura de sockaddr
[in, out] addrlen
Um ponteiro opcional para um inteiro que contém o comprimento da estrutura de de soquete
[in] lpfnCondition
O endereço de uma função de condição opcional especificada pelo aplicativo que tomará uma decisão de aceitação/rejeição com base nas informações de chamador passadas como parâmetros e, opcionalmente, criará ou ingressará em um grupo de soquetes atribuindo um valor apropriado ao parâmetro de resultado g dessa função. Se esse parâmetro for NULL, nenhuma função de condição será chamada.
[in] dwCallbackData
Dados de retorno de chamada passados de volta para a função de condição especificada pelo aplicativo como o valor do parâmetro dwCallbackData passado para a função de condição. Esse parâmetro só será aplicável se o parâmetro lpfnCondition não for NULL. Esse parâmetro não é interpretado pelos Soquetes do Windows.
Valor de retorno
Se nenhum erro ocorrer, WSAAccept retornará um valor do tipo SOCKET que é um descritor para o soquete aceito. Caso contrário, um valor de INVALID_SOCKET é retornado e um código de erro específico pode ser recuperado chamando WSAGetLastError.
O inteiro referenciado por addrlen contém inicialmente a quantidade de espaço apontada por do suplemento. Ao retornar, ele conterá o comprimento real em bytes do endereço retornado.
Código de erro | Significado |
---|---|
Foi feita uma tentativa de acessar um soquete de forma proibida por suas permissões de acesso. Esse erro será retornado se a solicitação de conexão oferecida tiver ultrapassado ou sido retirada. | |
Nenhuma conexão poderia ser feita porque o computador de destino a recusou ativamente. Esse erro será retornado se a solicitação de conexão tiver sido rejeitada com força, conforme indicado no valor retornado da função de condição (CF_REJECT). | |
Uma conexão existente foi fechada à força pelo host remoto. Esse erro é retornado de uma conexão de entrada foi indicado, mas posteriormente foi encerrado pelo par remoto antes de aceitar a chamada. | |
O sistema detectou um endereço de ponteiro inválido ao tentar usar um argumento de ponteiro em uma chamada. Esse erro é retornado do parâmetro |
|
Uma operação de bloqueio foi interrompida por uma chamada para WSACancelBlockingCall. Esse erro será retornado se uma chamada do Windows Sockets 1.1 de bloqueio tiver sido cancelada por meio de WSACancelBlockingCall . | |
Uma operação de bloqueio está sendo executada no momento. Esse erro será retornado se uma chamada de bloqueio do Windows Sockets 1.1 estiver em andamento. | |
Um argumento inválido foi fornecido. Esse erro será retornado se escuta não tiver sido invocado antes de WSAAccept, o valor retornado da função de condição não for válido ou qualquer caso em que o soquete especificado esteja em um estado inválido. | |
Soquetes abertos demais. Esse erro será retornado se a fila não estiver cheia após a entrada para WSAAccept e não houver descritores de soquete disponíveis. | |
Uma operação de soquete encontrou uma rede morta. Esse erro será retornado se o subsistema de rede falhar. | |
Não foi possível executar uma operação em um soquete porque o sistema não tinha espaço suficiente no buffer ou porque uma fila estava cheia. Esse erro será retornado se nenhum espaço de buffer estiver disponível. | |
Uma operação foi tentada em algo que não é um soquete. Esse erro será retornado se o descritor de soquete passado no parâmetro do |
|
A família de protocolos não foi configurada no sistema ou não existe nenhuma implementação para ela. Esse erro será retornado se o soquete referenciado não for um tipo que dê suporte ao serviço orientado à conexão. | |
Uma operação de soquete sem bloqueio não pôde ser concluída imediatamente. Esse erro será retornado se o soquete estiver marcado como não desbloqueado e nenhuma conexão estiver presente para ser aceita. | |
O aplicativo não chamou WSAStartup ou WSAStartup falhou. Esse erro é retornado de uma chamada bem-sucedida para a função WSAStartup não ocorrer antes de usar essa função. | |
Isso geralmente é um erro temporário durante a resolução de nome de host e significa que o servidor local não recebeu uma resposta de um servidor autoritativo. Esse erro será retornado se a aceitação da solicitação de conexão tiver sido adiada conforme indicado no valor retornado da função de condição (CF_DEFER). |
Observações
A função WSAAccept extrai a primeira conexão na fila de conexões pendentes no soquete e verifica-a na função de condição, desde que a função de condição seja especificada (ou seja, não NULL). Se a função condição retornar CF_ACCEPT, WSAAccept criará um novo soquete. O soquete recém-criado tem as mesmas propriedades do soquete incluindo eventos assíncronos registrados com WSAAsyncSelect ou com WSAEventSelect. Se a função de condição retornar CF_REJECT, WSAAccept rejeitará a solicitação de conexão. A função de condição é executada no mesmo thread que essa função e deve retornar o mais rápido possível. Se a decisão não puder ser tomada imediatamente, a função de condição deverá retornar CF_DEFER para indicar que nenhuma decisão foi tomada e nenhuma ação sobre essa solicitação de conexão deverá ser tomada pelo provedor de serviços. Quando o aplicativo estiver pronto para executar uma ação na solicitação de conexão, ele invocará WSAAccept novamente e retornará CF_ACCEPT ou CF_REJECT como um valor retornado da função de condição.
Um soquete no modo padrão (bloqueio) será bloqueado até que uma conexão esteja presente quando um aplicativo chamar WSAAccept e nenhuma conexão estiver pendente na fila.
Um soquete no modo de não bloqueio (bloqueio) falha com o erro WSAEWOULDBLOCK quando um aplicativo chama WSAAccept e nenhuma conexão está pendente na fila. Depois que WSAAccept é bem-sucedido e retorna um novo identificador de soquete, o soquete aceito não pode ser usado para aceitar mais conexões. O soquete original permanece aberto e escuta novas solicitações de conexão.
O parâmetro do suplemento
Um protótipo da função de condição é definido no arquivo de cabeçalho Winsock2.h
como LPCONDITIONPROC, da seguinte maneira.
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
);
O ConditionFunc
O parâmetro lpCallerId aponta para uma estrutura WSABUF que contém o endereço da entidade de conexão, onde seu parâmetro len é o comprimento do buffer em bytes e seu parâmetro buf é um ponteiro para o buffer. O lpCallerData é um parâmetro de valor que contém todos os dados do usuário. As informações nesses parâmetros são enviadas junto com a solicitação de conexão. Se nenhum dado de chamada ou identificação de chamador estiver disponível, os parâmetros correspondentes serão NULL. Muitos protocolos de rede não dão suporte a dados de chamadas em tempo de conexão. A maioria dos protocolos de rede convencionais pode ser esperada para dar suporte a informações de identificador de chamador no momento da solicitação de conexão. A parte buf da WSABUF
O parâmetro
O parâmetro lpGQOS
O lpCalleeId é um parâmetro que contém o endereço local da entidade conectada. A parte
O lpCalleeData é um parâmetro de resultado usado pela função de condição para fornecer dados do usuário de volta à entidade de conexão. O lpCalleeData->len inicialmente contém o comprimento do buffer alocado pelo provedor de serviços e apontado por lpCalleeData->buf. Um valor zero significa que não há suporte para a passagem de dados do usuário para o chamador. A função de condição deve copiar até lpCalleeData->len bytes de dados em lpCalleeData->bufe, em seguida, atualizar lpCalleeData->len para indicar o número real de bytes transferidos. Se nenhum dado do usuário for passado de volta para o chamador, a função de condição deverá definir lpCalleeData->len como zero. O formato de todos os dados de endereço e de usuário é específico para a família de endereços à qual o soquete pertence.
O parâmetro g é atribuído dentro da função de condição para indicar qualquer uma das seguintes ações:
- Se g for um identificador de grupo de soquetes existente, adicione a esse grupo, desde que todos os requisitos definidos por esse grupo sejam atendidos.
- Se g = SG_UNCONSTRAINED_GROUP, crie um grupo de soquetes não treinado e tenha como o primeiro membro.
- Se g = SG_CONSTRAINED_GROUP, crie um grupo de soquetes restrito e tenha como o primeiro membro.
- Se g = zero, nenhuma operação de grupo será executada.
O valor do parâmetro dwCallbackData
código de exemplo
O exemplo a seguir demonstra o uso da função#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: Essa função tem suporte para aplicativos da Windows Phone Store no Windows Phone 8 e posterior.
windows 8.1 e Windows Server 2012 R2: essa função tem suporte para aplicativos da Windows Store no Windows 8.1, Windows Server 2012 R2 e posterior.
Requisitos
Requisito | Valor |
---|---|
de cliente com suporte mínimo | Windows 8.1, Windows Vista [aplicativos da área de trabalho | Aplicativos UWP] |
servidor com suporte mínimo | Windows Server 2003 [aplicativos da área de trabalho | Aplicativos UWP] |
da Plataforma de Destino |
Windows |
cabeçalho | winsock2.h |
biblioteca | Ws2_32.lib |
de DLL |
Ws2_32.dll |
Consulte também
do Winsock Functions
referência Winsock