Compartilhar via


Função sendto (winsock.h)

A função sendto envia dados para um destino específico.

Sintaxe

int sendto(
  [in] SOCKET         s,
  [in] const char     *buf,
  [in] int            len,
  [in] int            flags,
  [in] const sockaddr *to,
  [in] int            tolen
);

Parâmetros

[in] s

Um descritor que identifica um soquete (possivelmente conectado).

[in] buf

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

[in] len

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

[in] flags

Um conjunto de sinalizadores que especificam a maneira como a chamada é feita.

[in] to

Um ponteiro opcional para uma estrutura sockaddr que contém o endereço do soquete de destino.

[in] tolen

O tamanho, em bytes, do endereço apontado pelo parâmetro to .

Valor retornado

Se nenhum erro ocorrer, sendto retornará o número total de bytes enviados, que pode ser menor que o número indicado por 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 o parâmetro SO_BROADCAST para permitir o uso do endereço de difusão.
WSAEINVAL
Um sinalizador desconhecido foi especificado ou MSG_OOB foi especificado para um soquete com SO_OOBINLINE habilitado.
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
Os parâmetros buf ou to não fazem parte do espaço de endereço do usuário ou o parâmetro tolen é muito pequeno.
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 (somente soquetes orientados à conexão).
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 para 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.
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.
WSAEADDRNOTAVAIL
O endereço remoto não é um endereço válido, por exemplo, ADDR_ANY.
WSAEAFNOSUPPORT
Os endereços na família especificada não podem ser usados com este soquete.
WSAEDESTADDRREQ
Endereço de destino necessário.
WSAENETUNREACH
A rede não pode ser alcançada através deste host neste momento.
WSAEHOSTUNREACH
Uma operação de soquete foi tentada em um host inacessível.
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 sendto é usada para gravar dados de saída em um soquete. Para soquetes orientados a mensagens, deve-se tomar cuidado para não exceder o tamanho máximo do pacote das sub-redes subjacentes, que podem ser obtidos usando getsockopt para recuperar o valor da opção de soquete SO_MAX_MSG_SIZE. Se os dados forem muito longos para passar atomicamente pelo protocolo subjacente, o erro WSAEMSGSIZE será retornado e nenhum dado será transmitido.

O parâmetro to pode ser qualquer endereço válido na família de endereços do soquete, incluindo uma transmissão ou qualquer endereço multicast. Para enviar para um endereço de transmissão, um aplicativo deve ter usado setsockopt com SO_BROADCAST habilitado. Caso contrário, sendto falhará com o código de erro WSAEACCES. Para TCP/IP, um aplicativo pode enviar para qualquer endereço multicast (sem se tornar um membro do grupo).

Nota Se um soquete for aberto, uma chamada setsockopt será feita e, em seguida, uma chamada sendto será feita, o Windows Sockets executará uma chamada de função de associação implícita.
 
Se o soquete estiver desvinculado, os valores exclusivos serão atribuídos à associação local pelo sistema e o soquete será marcado como associado. Se o soquete estiver conectado, a função getsockname poderá ser usada para determinar o endereço IP local e a porta associada ao soquete.

Se o soquete não estiver conectado, o
A função getsockname pode ser usada para determinar o número da porta local associado ao soquete, mas o endereço IP retornado é definido como o endereço curinga do protocolo fornecido (por exemplo, INADDR_ANY ou "0.0.0.0" para IPv4 e IN6ADDR_ANY_INIT ou "::" para IPv6).

A conclusão bem-sucedida de um sendto não indica que os dados foram entregues com êxito.

A função sendto normalmente é usada em um soquete sem conexão para enviar um datagrama para um soquete par específico identificado pelo parâmetro to . Mesmo que o soquete sem conexão tenha sido conectado anteriormente a um endereço específico, o parâmetro to substituirá o endereço de destino somente para esse datagrama específico. Em um soquete orientado à conexão, os parâmetros to e tolen são ignorados, tornando sendto equivalente ao envio.

Nota Ao emitir uma chamada winsock de bloqueio, como sendto, 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 sendto .
#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")

int main()
{

    int iResult;
    WSADATA wsaData;

    SOCKET SendSocket = INVALID_SOCKET;
    sockaddr_in RecvAddr;

    unsigned short Port = 27015;

    char SendBuf[1024];
    int BufLen = 1024;

    //----------------------
    // 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 sending data
    SendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (SendSocket == INVALID_SOCKET) {
        wprintf(L"socket failed with error: %ld\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }
    //---------------------------------------------
    // Set up the RecvAddr structure with the IP address of
    // the receiver (in this example case "192.168.1.1")
    // and the specified port number.
    RecvAddr.sin_family = AF_INET;
    RecvAddr.sin_port = htons(Port);
    RecvAddr.sin_addr.s_addr = inet_addr("192.168.1.1");

    //---------------------------------------------
    // Send a datagram to the receiver
    wprintf(L"Sending a datagram to the receiver...\n");
    iResult = sendto(SendSocket,
                     SendBuf, BufLen, 0, (SOCKADDR *) & RecvAddr, sizeof (RecvAddr));
    if (iResult == SOCKET_ERROR) {
        wprintf(L"sendto failed with error: %d\n", WSAGetLastError());
        closesocket(SendSocket);
        WSACleanup();
        return 1;
    }
    //---------------------------------------------
    // When the application is finished sending, close the socket.
    wprintf(L"Finished sending. Closing socket.\n");
    iResult = closesocket(SendSocket);
    if (iResult == SOCKET_ERROR) {
        wprintf(L"closesocket failed with error: %d\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }
    //---------------------------------------------
    // Clean up and quit.
    wprintf(L"Exiting.\n");
    WSACleanup();
    return 0;
}


Para soquetes usando IP (versão 4)

Para enviar uma transmissão (somente em um SOCK_DGRAM), o endereço apontado pelo parâmetro to pode ser construído para conter o endereço IPv4 especial INADDR_BROADCAST (definido em Winsock2.h), juntamente com o número da porta pretendido. Se o endereço apontado pelo parâmetro to contiver o endereço INADDR_BROADCAST e a porta pretendida, a transmissão será enviada em todas as interfaces para essa porta.

Se a transmissão deve ser enviada somente em uma interface específica, o endereço apontado pelo parâmetro to deverá conter o endereço de transmissão da sub-rede para a interface e a porta pretendida. Por exemplo, um endereço de rede IPv4 de 192.168.1.0 com uma máscara de sub-rede de 255.255.255.0 usaria um endereço de transmissão de sub-rede de 192.168.1.255.

Geralmente, não é recomendável que um datagrama de difusão exceda o tamanho em que a fragmentação pode ocorrer, o que implica que a parte de dados do datagram (excluindo cabeçalhos) não deve exceder 512 bytes.

Se nenhum espaço de buffer estiver disponível no sistema de transporte para manter os dados a serem transmitidos, sendto bloqueará, a menos que o soquete tenha sido colocado em um modo sem bloqueio. Em soquetes orientados a fluxo sem bloqueio, o número de bytes gravados pode ser entre 1 e o comprimento solicitado, dependendo da disponibilidade do buffer nos sistemas cliente e servidor. A função select, WSAAsyncSelect ou WSAEventSelect pode ser usada para determinar quando é possível enviar mais dados.

Chamar sendto com um len de zero é permitido e 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 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 . Este último é 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 fluxo, como somente SOCK_STREAM).
 

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

Wsaeventselect

Funções Winsock

Referência de Winsock

Recv

Recvfrom

select

send

socket