Função recv (winsock.h)

A função recv recebe dados de um soquete conectado ou de um soquete sem conexão associado.

Sintaxe

int recv(
  [in]  SOCKET s,
  [out] char   *buf,
  [in]  int    len,
  [in]  int    flags
);

Parâmetros

[in] s

O descritor que identifica um soquete conectado.

[out] buf

Um ponteiro para o buffer para receber os dados de entrada.

[in] len

O comprimento, em bytes, do buffer apontado pelo parâmetro buf .

[in] flags

Um conjunto de sinalizadores que influencia o comportamento dessa função. Consulte os comentários abaixo. Consulte a seção Comentários para obter detalhes sobre o valor possível para esse parâmetro.

Valor retornado

Se nenhum erro ocorrer, recv retornará o número de bytes recebidos e o buffer apontado pelo parâmetro buf conterá esses dados recebidos. Se a conexão tiver sido normalmente fechada, o valor retornado será zero.

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

Código do erro Significado
WSANOTINITIALISED
Uma chamada WSAStartup bem-sucedida deve ocorrer antes de usar essa função.
WSAENETDOWN
O subsistema de rede falhou.
WSAEFAULT
O parâmetro buf não está completamente contido em uma parte válida do espaço de endereço do usuário.
WSAENOTCONN
O soquete não está conectado.
WSAEINTR
A chamada (bloqueio) foi cancelada por meio de WSACancelBlockingCall.
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.
WSAENETRESET
Para um soquete orientado a conexão, esse erro indica que a conexão foi interrompida devido à atividade keep alive que detectou uma falha enquanto a operação estava em andamento. Para um soquete de datagrama, este erro indica que a vida útil venceu.
WSAENOTSOCK
O descritor não é um soquete.
WSAEOPNOTSUPP
MSG_OOB foi especificado, mas o soquete não é estilo de fluxo, como tipo SOCK_STREAM, não há suporte para dados OOB no domínio de comunicação associado a esse soquete ou o soquete é unidirecional e dá suporte apenas a operações de envio.
WSAESHUTDOWN
O soquete foi desligado; não é possível receber em um soquete após o desligamento ter sido invocado com a definição de como SD_RECEIVE ou SD_BOTH.
WSAEWOULDBLOCK
O soquete é marcado como não desbloqueado e a operação de recebimento seria bloqueada.
WSAEMSGSIZE
A mensagem era muito grande para caber no buffer especificado e foi truncada.
WSAEINVAL
O soquete não foi associado à associação ou um sinalizador desconhecido foi especificado ou MSG_OOB foi especificado para um soquete com SO_OOBINLINE habilitado ou (somente para soquetes de fluxo de bytes) len era zero ou negativo.
WSAECONNABORTED
O circuito virtual foi encerrado por causa do tempo limite ou outra falha. O aplicativo deve fechar o soquete porque ele não pode ser mais usado.
WSAETIMEDOUT
A conexão foi cancelada porque houve falha na rede ou porque o sistema falhou ao responder ao peer system.
WSAECONNRESET
O circuito virtual foi redefinido pelo lado remoto executando um fechamento forçado ou por anulação. O aplicativo deve fechar o soquete porque ele não pode ser mais usado. Em um soquete UDP-datagram, esse erro indicaria que uma operação de envio anterior resultou em uma mensagem "Porta Inacessível" ICMP.

Comentários

A função recv é usada para ler dados de entrada em soquetes orientados à conexão ou soquetes sem conexão. Ao usar um protocolo orientado a conexão, os soquetes devem ser conectados antes de chamar recv. Ao usar um protocolo sem conexão, os soquetes devem ser associados antes de chamar recv.

O endereço local do soquete deve ser conhecido. Para aplicativos de servidor, use uma função de associação explícita ou uma função de aceitação implícita ou WSAAccept . A associação explícita é desencorajada para aplicativos cliente. Para aplicativos cliente, o soquete pode se tornar associado implicitamente a um endereço local usando connect, WSAConnect, sendto, WSASendTo ou WSAJoinLeaf.

Para soquetes conectados ou sem conexão, a função recv restringe os endereços dos quais as mensagens recebidas são aceitas. A função retorna apenas mensagens do endereço remoto especificado na conexão. As mensagens de outros endereços são (silenciosamente) descartadas.

Para soquetes orientados à conexão (tipo SOCK_STREAM por exemplo), chamar recv retornará o máximo de dados que estiver disponível no momento, até o tamanho do buffer especificado. Se o soquete tiver sido configurado para recepção em linha de dados OOB (opção de soquete SO_OOBINLINE) e os dados OOB ainda não forem lidos, somente os dados OOB serão retornados. O aplicativo pode usar o comando ioctlsocket ou WSAIoctlSIOCATMARK para determinar se ainda há mais dados OOB a serem lidos.

Para soquetes sem conexão (tipo SOCK_DGRAM ou outros soquetes orientados a mensagens), os dados são extraídos do primeiro datagrama enfileirado (mensagem) do endereço de destino especificado pela função connect .

Se o datagrama ou a mensagem for maior que o buffer especificado, o buffer será preenchido com a primeira parte do datagrama e o recv gerará o erro WSAEMSGSIZE. Para protocolos não confiáveis (por exemplo, UDP), os dados em excesso são perdidos; para protocolos confiáveis, os dados são retidos pelo provedor de serviços até que sejam lidos com êxito chamando recv com um buffer grande o suficiente.

Se nenhum dado de entrada estiver disponível no soquete, a chamada recv bloqueará e aguardará a chegada dos dados de acordo com as regras de bloqueio definidas para WSARecv com o sinalizador MSG_PARTIAL não definido, a menos que o soquete não esteja sendo desbloqueado. Nesse caso, um valor de SOCKET_ERROR é retornado com o código de erro definido como WSAEWOULDBLOCK. As funções select, WSAAsyncSelect ou WSAEventSelect podem ser usadas para determinar quando mais dados chegam.

Se o soquete for orientado à conexão e o lado remoto tiver desligado a conexão normalmente e todos os dados tiverem sido recebidos, um recv será concluído imediatamente com zero bytes recebidos. Se a conexão tiver sido redefinida, um recv falhará com o erro WSAECONNRESET.

O parâmetro flags pode ser usado para influenciar o comportamento da invocação de função além das opções especificadas para o soquete associado. A semântica dessa função é determinada pelas opções de soquete e pelo parâmetro flags . O valor possível do parâmetro flags é construído usando o operador OR bit a bit com qualquer um dos valores a seguir.

Valor Significado
MSG_PEEK Espia os dados de entrada. Os dados são copiados para o buffer, mas não são removidos da fila de entrada.
MSG_OOB Processa dados fora de banda (OOB).
MSG_WAITALL A solicitação de recebimento será concluída somente quando ocorrer um dos seguintes eventos:
  • O buffer fornecido pelo chamador está completamente cheio.
  • A conexão foi fechada.
  • A solicitação foi cancelada ou ocorreu um erro.
Observe que, se o transporte subjacente não der suporte a MSG_WAITALL ou se o soquete estiver em um modo sem bloqueio, essa chamada falhará com WSAEOPNOTSUPP. Além disso, se MSG_WAITALL for especificado junto com MSG_OOB, MSG_PEEK ou MSG_PARTIAL, essa chamada falhará com WSAEOPNOTSUPP. Não há suporte para esse sinalizador em soquetes de datagrama ou soquetes orientados a mensagens.
 
Nota Ao emitir uma chamada winsock de bloqueio, como recv, winsock pode precisar esperar por 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 de código a seguir mostra o uso da função recv .
#define WIN32_LEAN_AND_MEAN

#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>

// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")

#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"

int __cdecl main() {

    //----------------------
    // Declare and initialize variables.
    WSADATA wsaData;
    int iResult;

    SOCKET ConnectSocket = INVALID_SOCKET;
    struct sockaddr_in clientService; 

    char *sendbuf = "this is a test";
    char recvbuf[DEFAULT_BUFLEN];
    int recvbuflen = DEFAULT_BUFLEN;
  
    //----------------------
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != NO_ERROR) {
      printf("WSAStartup failed: %d\n", iResult);
      return 1;
    }

    //----------------------
    // Create a SOCKET for connecting to server
    ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (ConnectSocket == INVALID_SOCKET) {
        printf("Error at socket(): %ld\n", WSAGetLastError() );
        WSACleanup();
        return 1;
    }

    //----------------------
    // The sockaddr_in structure specifies the address family,
    // IP address, and port of the server to be connected to.
    clientService.sin_family = AF_INET;
    clientService.sin_addr.s_addr = inet_addr( "127.0.0.1" );
    clientService.sin_port = htons( 27015 );

    //----------------------
    // Connect to server.
    iResult = connect( ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService) );
    if ( iResult == SOCKET_ERROR) {
        closesocket (ConnectSocket);
        printf("Unable to connect to server: %ld\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }

    // Send an initial buffer
    iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
    if (iResult == SOCKET_ERROR) {
        printf("send failed: %d\n", WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }

    printf("Bytes Sent: %ld\n", iResult);

    // shutdown the connection since no more data will be sent
    iResult = shutdown(ConnectSocket, SD_SEND);
    if (iResult == SOCKET_ERROR) {
        printf("shutdown failed: %d\n", WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }

    // Receive until the peer closes the connection
    do {

        iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
        if ( iResult > 0 )
            printf("Bytes received: %d\n", iResult);
        else if ( iResult == 0 )
            printf("Connection closed\n");
        else
            printf("recv failed: %d\n", WSAGetLastError());

    } while( iResult > 0 );

    // cleanup
    closesocket(ConnectSocket);
    WSACleanup();

    return 0;
}


Código de exemplo

Para obter mais informações e outro exemplo da função recv, consulte Introdução With Winsock.

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 em Windows 8.1, Windows Server 2012 R2 e posterior.

Requisitos

   
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 winsock.h (inclua Winsock2.h)
Biblioteca Ws2_32.lib
DLL Ws2_32.dll

Confira também

WSAAsyncSelect

WSARecv

WSARecvEx

Funções Winsock

Referência de Winsock

Recvfrom

select

send

socket