Função send (winsock2.h)

A função send envia dados em um soquete conectado.

Sintaxe

int WSAAPI send(
  [in] SOCKET     s,
  [in] const char *buf,
  [in] int        len,
  [in] int        flags
);

Parâmetros

[in] s

Um descritor que identifica um soquete conectado.

[in] buf

Um ponteiro para um buffer que contém os dados a serem transmitidos.

[in] len

O comprimento, em bytes, dos dados no buffer apontados pelo parâmetro buf .

[in] flags

Um conjunto de sinalizadores que especificam a maneira como a chamada é feita. Esse parâmetro é construído usando o operador OR bit a bit com qualquer um dos valores a seguir.

Valor Significado
MSG_DONTROUTE
Especifica que os dados não devem estar sujeitos ao roteamento. Um provedor de serviços do Windows Sockets pode optar por ignorar esse sinalizador.
MSG_OOB
Envia dados OOB (soquete no estilo de fluxo, como somente SOCK_STREAM).

Retornar valor

Se nenhum erro ocorrer, send retornará o número total de bytes enviados, que pode ser menor do que o número solicitado para ser enviado no parâmetro len . Caso contrário, um valor de SOCKET_ERROR é retornado e um código de erro específico pode 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.
WSAEACCES
O endereço solicitado é um endereço de transmissão, mas o sinalizador apropriado não foi definido. Chame setsockopt com a opção de soquete SO_BROADCAST para habilitar o uso do endereço de difusão.
WSAEINTR
Uma chamada do Windows Sockets 1.1 de bloqueio foi cancelada por meio de WSACancelBlockingCall.
WSAEINPROGRESS
Uma chamada do Windows Sockets 1.1 de bloqueio está em andamento ou o provedor de serviços ainda está processando uma função de retorno de chamada.
WSAEFAULT
O parâmetro buf não está completamente contido em uma parte válida do espaço de endereço do usuário.
WSAENETRESET
A conexão foi interrompida porque a atividade de manutenção de funcionamento detectou uma falha enquanto a operação estava em andamento.
WSAENOBUFS
Nenhum espaço de buffer disponível.
WSAENOTCONN
O soquete não está conectado.
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 recebimento.
WSAESHUTDOWN
O soquete foi desligado; não é possível enviar em um soquete após o desligamento ter sido invocado com a definição de como SD_SEND ou SD_BOTH.
WSAEWOULDBLOCK
O soquete é marcado como não desbloqueio e a operação solicitada seria bloqueada.
WSAEMSGSIZE
O soquete é orientado a mensagens e a mensagem é maior do que o máximo suportado pelo transporte subjacente.
WSAEHOSTUNREACH
O host remoto não pode ser acessado desse host no momento.
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.
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.
WSAECONNRESET
O circuito virtual foi redefinido pelo lado remoto executando um fechamento forçado ou por anulação. Para soquetes UDP, o host remoto não pôde entregar um datagrama UDP enviado anteriormente e respondeu com um pacote ICMP "Porta Inacessível". O aplicativo deve fechar o soquete porque ele não pode ser mais usado.
WSAETIMEDOUT
A conexão foi descartada, devido a uma falha de rede ou porque o sistema na outra extremidade ficou inativo sem aviso prévio.

Comentários

A função send é usada para gravar dados de saída em um soquete conectado.

Para soquetes orientados a mensagens (família de endereços de AF_INET ou AF_INET6, tipo de SOCK_DGRAM e protocolo de IPPROTO_UDP, por exemplo), deve-se tomar cuidado para não exceder o tamanho máximo do pacote do provedor subjacente. O tamanho máximo do pacote de mensagem para um provedor pode ser obtido chamando getsockopt com o parâmetro optname definido como SO_MAX_MSG_SIZE para recuperar o valor da opção de soquete. Se os dados forem muito longos para passar atomicamente pelo protocolo subjacente, o erro WSAEMSGSIZE será retornado e nenhum dado será transmitido.

A conclusão bem-sucedida de uma função de envio não indica que os dados foram entregues e recebidos com êxito ao destinatário. Essa função indica apenas que os dados foram enviados com êxito.

Se nenhum espaço de buffer estiver disponível no sistema de transporte para manter os dados a serem transmitidos, o envio será bloqueado, a menos que o soquete tenha sido colocado no modo sem bloqueio. Em soquetes orientados ao fluxo sem bloqueio, o número de bytes gravados pode ser entre 1 e o comprimento solicitado, dependendo da disponibilidade do buffer nos computadores cliente e servidor. As funções select, WSAAsyncSelect ou WSAEventSelect podem ser usadas para determinar quando é possível enviar mais dados.

Chamar enviar com um parâmetro len de zero é permitido e será tratado por implementações como bem-sucedido. Nesses casos, send retornará zero como um valor válido. Para soquetes orientados a mensagens, um datagrama de transporte de comprimento zero é enviado.

O parâmetro flags pode ser usado para influenciar o comportamento da função além das opções especificadas para o soquete associado. A semântica da função send é determinada por todas as opções definidas anteriormente no soquete especificado no parâmetro s e pelo parâmetro flags passado para a função send .

A ordem das chamadas feitas para enviar também é a ordem na qual os buffers são transmitidos para a camada de transporte. send não deve ser chamado no mesmo soquete orientado a fluxo simultaneamente de threads diferentes, pois alguns provedores winsock podem dividir uma solicitação de envio grande em várias transmissões, e isso pode levar a intercalação de dados não intencionais de várias solicitações de envio simultâneas no mesmo soquete orientado a fluxo.

Nota Ao emitir uma chamada winsock de bloqueio, como enviar, 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íncrona) agendada no mesmo thread. Emitir 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 tentado pelos clientes winsock.
 

Código de exemplo

O exemplo a seguir demonstra o uso da função send .
#ifndef UNICODE
#define UNICODE
#endif

#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 main() {

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

    SOCKET ConnectSocket = INVALID_SOCKET;
    struct sockaddr_in clientService; 

    int recvbuflen = DEFAULT_BUFLEN;
    char *sendbuf = "Client: sending data test";
    char recvbuf[DEFAULT_BUFLEN] = "";

    //----------------------
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != NO_ERROR) {
        wprintf(L"WSAStartup failed with error: %d\n", iResult);
        return 1;
    }

    //----------------------
    // Create a SOCKET for connecting to server
    ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (ConnectSocket == 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 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( DEFAULT_PORT );

    //----------------------
    // Connect to server.
    iResult = connect( ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService) );
    if (iResult == SOCKET_ERROR) {
        wprintf(L"connect failed with error: %d\n", WSAGetLastError() );
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
  }

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

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

    // shutdown the connection since no more data will be sent
    iResult = shutdown(ConnectSocket, SD_SEND);
    if (iResult == SOCKET_ERROR) {
        wprintf(L"shutdown failed with error: %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 )
            wprintf(L"Bytes received: %d\n", iResult);
        else if ( iResult == 0 )
            wprintf(L"Connection closed\n");
        else
            wprintf(L"recv failed with error: %d\n", WSAGetLastError());

    } while( iResult > 0 );


    // close the socket
    iResult = closesocket(ConnectSocket);
    if (iResult == SOCKET_ERROR) {
        wprintf(L"close failed with error: %d\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }

    WSACleanup();
    return 0;
}

Código de exemplo

Para obter outro exemplo que usa a função send, consulte Introdução With Winsock.

Notas sobre soquetes IrDA

  • O arquivo de cabeçalho Af_irda.h deve ser incluído explicitamente.
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 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

Introdução com Winsock

WSAAsyncSelect

Wsaeventselect

Funções Winsock

Referência de Winsock

Recv

Recvfrom

select

Sendto

socket