Funzione sendto (winsock.h)
La funzione sendto invia dati a una destinazione specifica.
Sintassi
int sendto(
[in] SOCKET s,
[in] const char *buf,
[in] int len,
[in] int flags,
[in] const sockaddr *to,
[in] int tolen
);
Parametri
[in] s
Descrittore che identifica un socket (possibilmente connesso).
[in] buf
Puntatore a un buffer contenente i dati da trasmettere.
[in] len
Lunghezza, in byte, dei dati a cui punta il parametro buf .
[in] flags
Set di flag che specificano il modo in cui viene effettuata la chiamata.
[in] to
Puntatore facoltativo a una struttura sockaddr che contiene l'indirizzo del socket di destinazione.
[in] tolen
Dimensioni, in byte, dell'indirizzo a cui punta il parametro.
Valore restituito
Se non si verifica alcun errore, sendto restituisce il numero totale di byte inviati, che può essere minore del numero indicato da len. In caso contrario, viene restituito un valore di SOCKET_ERROR e un codice di errore specifico può essere recuperato chiamando WSAGetLastError.
Codice di errore | Significato |
---|---|
Prima di usare questa funzione, è necessario eseguire una chiamata WSAStartup riuscita. | |
Il sottosistema di rete non è riuscito. | |
L'indirizzo richiesto è un indirizzo di trasmissione, ma il flag appropriato non è stato impostato. Chiama setockopt con il parametro SO_BROADCAST per consentire l'uso dell'indirizzo di trasmissione. | |
È stato specificato un flag sconosciuto oppure MSG_OOB è stato specificato per un socket con SO_OOBINLINE abilitato. | |
Una chiamata di Windows Sockets 1.1 bloccata è stata annullata tramite WSACancelBlockingCall. | |
Una chiamata windows Sockets 1.1 bloccata è in corso oppure il provider di servizi sta ancora elaborando una funzione di callback. | |
I parametri buf o to parameters non fanno parte dello spazio degli indirizzi utente oppure il parametro tolen è troppo piccolo. | |
La connessione è stata interrotta a causa dell'attività keep-alive che rileva un errore durante l'operazione in corso. | |
Nessuno spazio di buffer disponibile. | |
Il socket non è connesso (solo socket orientati alla connessione). | |
Il descrittore non è un socket. | |
MSG_OOB è stato specificato, ma il socket non è in stile di flusso, ad esempio il tipo SOCK_STREAM, i dati OOB non sono supportati nel dominio di comunicazione associato a questo socket o il socket è unidirectional e supporta solo le operazioni di ricezione. | |
Il socket è stato arrestato; non è possibile inviare su un socket dopo l'arresto richiamato con come impostare su SD_SEND o SD_BOTH. | |
Il socket è contrassegnato come non bloccante e l'operazione richiesta blocca. | |
Il socket è orientato al messaggio e il messaggio è maggiore del massimo supportato dal trasporto sottostante. | |
Impossibile raggiungere l'host remoto da questo host in questo momento. | |
Circuito virtuale terminato a causa di un timeout o di un altro errore. L'applicazione deve chiudere il socket che non è più utilizzabile. | |
Circuito virtuale reimpostato dal lato remoto durante l'esecuzione di una chiusura definitiva o anomala. Per i socket UDP, l'host remoto non è riuscito a recapitare un datagramma UDP inviato in precedenza e ha risposto con un pacchetto ICMP "Port Unreachable". L'applicazione deve chiudere il socket che non è più utilizzabile. | |
L'indirizzo remoto non è un indirizzo valido, ad esempio ADDR_ANY. | |
Impossibile utilizzare gli indirizzi della famiglia specificata con questo socket. | |
È necessario un indirizzo di destinazione. | |
Impossibile raggiungere la rete da questo host in questo momento. | |
Tentativo di operazione del socket verso un host non raggiungibile. | |
La connessione è stata eliminata, a causa di un errore di rete o perché il sistema sull'altra parte è stato disattivato senza preavviso. |
Commenti
La funzione sendto viene usata per scrivere dati in uscita in un socket. Per i socket orientati ai messaggi, è necessario prestare attenzione a non superare le dimensioni massime dei pacchetti massimi delle subnet sottostanti, che possono essere ottenute usando getsockopt per recuperare il valore dell'opzione socket SO_MAX_MSG_SIZE. Se i dati sono troppo lunghi per passare atomicamente attraverso il protocollo sottostante, l'errore WSAEMSGSIZE viene restituito e non vengono trasmessi dati.
Il parametro to può essere qualsiasi indirizzo valido nella famiglia di indirizzi del socket, inclusa una trasmissione o qualsiasi indirizzo multicast. Per inviare a un indirizzo di trasmissione, un'applicazione deve avere usato setockopt con SO_BROADCAST abilitato. In caso contrario, sendto avrà esito negativo con il codice di errore WSAEACCES. Per TCP/IP, un'applicazione può inviare a qualsiasi indirizzo multicast (senza diventare un membro del gruppo).
Se il socket non è connesso,
la funzione getsockname può essere usata per determinare il numero di porta locale associato al socket, ma l'indirizzo IP restituito è impostato sull'indirizzo jolly per il protocollo specificato, ad esempio INADDR_ANY o "0.0.0.0" per IPv4 e IN6ADDR_ANY_INIT o ":": per IPv6).
Il completamento di un sendto non indica che i dati sono stati recapitati correttamente.
La funzione sendto viene in genere usata in un socket senza connessione per inviare un datagram a un socket peer specifico identificato dal parametro . Anche se il socket senza connessione è stato connesso in precedenza a un indirizzo specifico, il parametro per eseguire l'override dell'indirizzo di destinazione solo per quel particolare datagram. In un socket orientato alla connessione, i parametri to e tolen vengono ignorati, rendendo sendto equivalente all'invio.
Codice di esempio
Nell'esempio seguente viene illustrato l'uso della funzione 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;
}
Per socket che usano IP (versione 4)
Per inviare una trasmissione (solo in un SOCK_DGRAM), l'indirizzo a cui punta il parametro può essere costruito per contenere l'indirizzo IPv4 speciale INADDR_BROADCAST (definito in Winsock2.h), insieme al numero di porta previsto. Se l'indirizzo puntato dal parametro a contiene l'indirizzo INADDR_BROADCAST e la porta prevista, la trasmissione verrà inviata su tutte le interfacce a tale porta.Se la trasmissione deve essere inviata solo in un'interfaccia specifica, l'indirizzo a cui punta il parametro deve contenere l'indirizzo di trasmissione della subnet per l'interfaccia e la porta prevista. Ad esempio, un indirizzo di rete IPv4 192.168.1.0 con una subnet mask pari a 255.255.255.0 userebbe un indirizzo di trasmissione subnet 192.168.1.255.
In genere è inadvisable per un datagram di trasmissione superare le dimensioni a cui può verificarsi la frammentazione, che implica che la parte dei dati del datagram (escluse le intestazioni) non deve superare i 512 byte.
Se non è disponibile spazio buffer all'interno del sistema di trasporto per contenere i dati da trasmettere, sendto bloccherà a meno che il socket non sia stato inserito in modalità non di blocco. Nei socket orientati al flusso, il numero di byte scritti può essere compreso tra 1 e la lunghezza richiesta, a seconda della disponibilità del buffer nei sistemi client e server. La funzione select, WSAAsyncSelect o WSAEventSelect può essere usata per determinare quando è possibile inviare altri dati.
La chiamata a sendto con un len pari a zero è consentita e restituirà zero come valore valido. Per i socket orientati ai messaggi, viene inviato un datagram di trasporto a lunghezza zero.
Il parametro flag può essere usato per influenzare il comportamento della chiamata alla funzione oltre le opzioni specificate per il socket associato. La semantica di questa funzione è determinata dalle opzioni del socket e dal parametro flag . Quest'ultimo viene costruito usando l'operatore OR bit per bit con uno dei valori seguenti.
Valore | Significato |
---|---|
MSG_DONTROUTE | Specifica che i dati non devono essere soggetti al routing. Un provider di servizi Windows Sockets può scegliere di ignorare questo flag. |
MSG_OOB | Invia dati OOB (socket in stile flusso, ad esempio SOCK_STREAM solo). |
Windows Phone 8: questa funzione è supportata per le app Windows Phone Store in Windows Phone 8 e versioni successive.
Windows 8.1 e Windows Server 2012 R2: questa funzione è supportata per le app di Windows Store in Windows 8.1, Windows Server 2012 R2 e versioni successive.
Requisiti
Client minimo supportato | Windows 8.1, Windows Vista [app desktop | App UWP] |
Server minimo supportato | Windows Server 2003 [app desktop | App UWP] |
Piattaforma di destinazione | Windows |
Intestazione | winsock.h (include Winsock2.h) |
Libreria | Ws2_32.lib |
DLL | Ws2_32.dll |