Condividi tramite


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
WSANOTINITIALISED
Prima di usare questa funzione, è necessario eseguire una chiamata WSAStartup riuscita.
WSAENETDOWN
Il sottosistema di rete non è riuscito.
WSAEACCES
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.
WSAEINVAL
È stato specificato un flag sconosciuto oppure MSG_OOB è stato specificato per un socket con SO_OOBINLINE abilitato.
WSAEINTR
Una chiamata di Windows Sockets 1.1 bloccata è stata annullata tramite WSACancelBlockingCall.
WSAEINPROGRESS
Una chiamata windows Sockets 1.1 bloccata è in corso oppure il provider di servizi sta ancora elaborando una funzione di callback.
WSAEFAULT
I parametri buf o to parameters non fanno parte dello spazio degli indirizzi utente oppure il parametro tolen è troppo piccolo.
WSAENETRESET
La connessione è stata interrotta a causa dell'attività keep-alive che rileva un errore durante l'operazione in corso.
WSAENOBUFS
Nessuno spazio di buffer disponibile.
WSAENOTCONN
Il socket non è connesso (solo socket orientati alla connessione).
WSAENOTSOCK
Il descrittore non è un socket.
WSAEOPNOTSUPP
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.
WSAESHUTDOWN
Il socket è stato arrestato; non è possibile inviare su un socket dopo l'arresto richiamato con come impostare su SD_SEND o SD_BOTH.
WSAEWOULDBLOCK
Il socket è contrassegnato come non bloccante e l'operazione richiesta blocca.
WSAEMSGSIZE
Il socket è orientato al messaggio e il messaggio è maggiore del massimo supportato dal trasporto sottostante.
WSAEHOSTUNREACH
Impossibile raggiungere l'host remoto da questo host in questo momento.
WSAECONNABORTED
Circuito virtuale terminato a causa di un timeout o di un altro errore. L'applicazione deve chiudere il socket che non è più utilizzabile.
WSAECONNRESET
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.
WSAEADDRNOTAVAIL
L'indirizzo remoto non è un indirizzo valido, ad esempio ADDR_ANY.
WSAEAFNOSUPPORT
Impossibile utilizzare gli indirizzi della famiglia specificata con questo socket.
WSAEDESTADDRREQ
È necessario un indirizzo di destinazione.
WSAENETUNREACH
Impossibile raggiungere la rete da questo host in questo momento.
WSAEHOSTUNREACH
Tentativo di operazione del socket verso un host non raggiungibile.
WSAETIMEDOUT
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).

Nota Se viene aperto un socket, viene eseguita una chiamata setockopt e viene eseguita una chiamata sendto , Windows Sockets esegue una chiamata di funzione di associazione implicita.
 
Se il socket non è in uscita, i valori univoci vengono assegnati all'associazione locale dal sistema e il socket viene contrassegnato come associato. Se il socket è connesso, la funzione getsockname può essere usata per determinare l'indirizzo IP locale e la porta associata al socket.

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.

Nota Quando si emette una chiamata Winsock bloccata, ad esempio sendto, Winsock potrebbe dover attendere un evento di rete prima che la chiamata possa completare. Winsock esegue un'attesa avvisabile in questa situazione, che può essere interrotta da una chiamata di routine asincrona pianificata nello stesso thread. L'emissione di un'altra chiamata winsock bloccata all'interno di un APC che ha interrotto una chiamata winsock in corso sullo stesso thread comporterà un comportamento non definito e non deve mai essere tentato dai client Winsock.
 

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

Vedi anche

WSAAsyncSelect

WSAEventSelect

Funzioni Winsock

Informazioni di riferimento su Winsock

Recv

recvfrom

select

send

Socket