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 |
---|---|
Uma chamada WSAStartup bem-sucedida deve ocorrer antes de usar essa função. | |
O subsistema de rede falhou. | |
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. | |
Um sinalizador desconhecido foi especificado ou MSG_OOB foi especificado para um soquete com SO_OOBINLINE habilitado. | |
Uma chamada do Windows Sockets 1.1 de bloqueio foi cancelada por meio de WSACancelBlockingCall. | |
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. | |
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. | |
A conexão foi interrompida porque a atividade de manutenção de funcionamento detectou uma falha enquanto a operação estava em andamento. | |
Nenhum espaço de buffer disponível. | |
O soquete não está conectado (somente soquetes orientados à conexão). | |
O descritor não é um soquete. | |
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. | |
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. | |
O soquete é marcado como não desbloqueio e a operação solicitada seria bloqueada. | |
O soquete é orientado a mensagens e a mensagem é maior do que o máximo suportado pelo transporte subjacente. | |
O host remoto não pode ser acessado desse host no momento. | |
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. | |
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. | |
O endereço remoto não é um endereço válido, por exemplo, ADDR_ANY. | |
Os endereços na família especificada não podem ser usados com este soquete. | |
Endereço de destino necessário. | |
A rede não pode ser alcançada através deste host neste momento. | |
Uma operação de soquete foi tentada em um host inacessível. | |
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).
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.
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 |