Compartilhar via


Função accept (winsock2.h)

A função accept permite uma tentativa de conexão de entrada em um soquete.

Sintaxe

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

Parâmetros

[in] s

Um descritor que identifica um soquete que foi colocado em um estado de escuta com a função de escuta . Na verdade, a conexão é feita com o soquete retornado por accept.

[out] addr

Um ponteiro opcional para um buffer que recebe o endereço da entidade de conexão, como é conhecido a camada de comunicações. O formato exato do parâmetro addr é determinado pela família de endereços que foi estabelecida quando o soquete da estrutura sockaddr foi criado.

[in, out] addrlen

Um ponteiro opcional para um inteiro que contém o comprimento da estrutura apontada pelo parâmetro addr .

Retornar valor

Se nenhum erro ocorrer, accept retornará um valor do tipo SOCKET que é um descritor para o novo soquete. Esse valor retornado é um identificador para o soquete no qual a conexão real é feita.

Caso contrário, um valor de INVALID_SOCKET será retornado e um código de erro específico poderá ser recuperado chamando WSAGetLastError.

O inteiro referenciado pelo addrlen inicialmente contém a quantidade de espaço apontada pelo complemento. No retorno, ele conterá o comprimento real em bytes do endereço retornado.

Código do erro Significado
WSANOTINITIALISED
Uma chamada WSAStartup bem-sucedida deve ocorrer antes de usar essa função.
WSAECONNRESET
Uma conexão de entrada foi indicada, mas foi posteriormente encerrada pelo par remoto antes de aceitar a chamada.
WSAEFAULT
O parâmetro addrlen é muito pequeno ou o complemento não é uma parte válida do espaço de endereço do usuário.
WSAEINTR
Uma chamada de bloqueio do Windows Sockets 1.1 foi cancelada por meio de WSACancelBlockingCall.
WSAEINVAL
A função de escuta não foi invocada antes de aceitar.
WSAEINPROGRESS
Uma chamada de bloqueio do Windows Sockets 1.1 está em andamento ou o provedor de serviços ainda está processando uma função de retorno de chamada.
WSAEMFILE
A fila não está vazia na entrada para aceitar e não há descritores disponíveis.
WSAENETDOWN
O subsistema de rede falhou.
WSAENOBUFS
Nenhum espaço de buffer disponível.
WSAENOTSOCK
O descritor não é um soquete.
WSAEOPNOTSUPP
O soquete referenciado não é um tipo que dá suporte ao serviço orientado à conexão.
WSAEWOULDBLOCK
O soquete é marcado como não desbloqueio e nenhuma conexão está presente para ser aceita.

Comentários

A função accept extrai a primeira conexão na fila de conexões pendentes no soquete s. Em seguida, ele cria e retorna um identificador para o novo soquete. O soquete recém-criado é o soquete que manipulará a conexão real; ele tem as mesmas propriedades do soquete s, incluindo os eventos assíncronos registrados com as funções WSAAsyncSelect ou WSAEventSelect .

A função accept pode bloquear o chamador até que uma conexão esteja presente se nenhuma conexão pendente estiver presente na fila e o soquete estiver marcado como bloqueio. Se o soquete estiver marcado como não desbloqueado e nenhuma conexão pendente estiver presente na fila, accept retornará um erro, conforme descrito a seguir. Após a conclusão bem-sucedida do accept retornar um novo identificador de soquete, o soquete aceito não poderá ser usado para aceitar mais conexões. O soquete original permanece aberto e escuta novas solicitações de conexão.

O complemento de parâmetro é um parâmetro de resultado preenchido com o endereço da entidade de conexão, como conhecido pela camada de comunicações. O formato exato do parâmetro addr é determinado pela família de endereços na qual a comunicação está ocorrendo. O addrlen é um parâmetro value-result; inicialmente, ele deve conter a quantidade de espaço apontada pelo complemento; no retorno, ele conterá o comprimento real (em bytes) do endereço retornado.

A função accept é usada com tipos de soquete orientados à conexão, como SOCK_STREAM. Se addr e/ou addrlen forem iguais a NULL, nenhuma informação sobre o endereço remoto do soquete aceito será retornada.

Nota Ao emitir uma chamada winsock de bloqueio, como accept, Winsock pode precisar aguardar um evento de rede antes que a chamada possa ser concluída. O Winsock executa uma espera alertável nessa situação, que pode ser interrompida por uma APC (chamada de procedimento assíncrono) agendada no mesmo thread. A emissão de outra chamada winsock de bloqueio dentro de um APC que interrompeu uma chamada Winsock de bloqueio contínuo no mesmo thread levará a um comportamento indefinido e nunca deve ser tentada por clientes Winsock.
 

Código de exemplo

O exemplo a seguir demonstra o uso da função 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 obter outro exemplo que usa a função accept, consulte Introdução With Winsock.

Notas para caixa eletrônico

Veja a seguir problemas importantes associados à configuração da conexão e devem ser considerados ao usar o ATM (Modo de Transferência Assíncrona) com o Windows Sockets 2:

  • As funções accept e WSAAccept não definem necessariamente os parâmetros de comprimento de endereço e endereço remotos. Portanto, ao usar o ATM, o chamador deve usar a função WSAAccept e colocar ATM_CALLING_PARTY_NUMBER_IE no membro ProviderSpecific da estrutura QoS , que está incluída no parâmetro lpSQOS da função de retorno de chamada usada de acordo com o WSAAccept.
  • Ao usar a função accept , perceba que a função pode retornar antes que o estabelecimento da conexão tenha percorrido toda a distância entre o remetente e o receptor. Isso ocorre porque a função accept retorna assim que recebe uma mensagem CONNECT ACK; no ATM, uma mensagem CONNECT ACK é retornada pela próxima opção no caminho assim que uma mensagem CONNECT é processada (em vez do CONNECT ACK que está sendo enviado pelo nó final para o qual a conexão é finalmente estabelecida). Dessa forma, os aplicativos devem perceber que, se os dados forem enviados imediatamente após o recebimento de uma mensagem CONNECT ACK, a perda de dados será possível, pois a conexão pode não ter sido estabelecida todo o caminho entre o remetente e o receptor.

Windows 8.1 e Windows Server 2012 R2: essa função tem suporte para aplicativos da Windows Store em Windows 8.1, Windows Server 2012 R2 e posteriores.

Requisitos

Requisito Valor
Cliente mínimo com suporte Windows 8.1, Windows Vista [aplicativos da área de trabalho | Aplicativos UWP]
Servidor mínimo com suporte Windows Server 2003 [aplicativos da área de trabalho | Aplicativos UWP]
Plataforma de Destino Windows
Cabeçalho winsock2.h
Biblioteca Ws2_32.lib
DLL Ws2_32.dll

Confira também

Wsaaccept

WSAAsyncSelect

Funções Winsock

Referência de Winsock

bind

connect

listen

select

Sockaddr

socket