Fonction sendto (winsock.h)

La fonction sendto envoie des données à une destination spécifique.

Syntaxe

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

Paramètres

[in] s

Descripteur identifiant un socket (éventuellement connecté).

[in] buf

Pointeur vers une mémoire tampon contenant les données à transmettre.

[in] len

Longueur, en octets, des données pointées par le paramètre buf .

[in] flags

Ensemble d’indicateurs qui spécifient la façon dont l’appel est effectué.

[in] to

Pointeur facultatif vers une structure sockaddr qui contient l’adresse du socket cible.

[in] tolen

Taille, en octets, de l’adresse pointée par le paramètre to .

Valeur retournée

Si aucune erreur ne se produit, sendto retourne le nombre total d’octets envoyés, qui peut être inférieur au nombre indiqué par len. Sinon, une valeur de SOCKET_ERROR est retournée et un code d’erreur spécifique peut être récupéré en appelant WSAGetLastError.

Code d'erreur Signification
WSANOTINITIALISED
Un appel WSAStartup réussi doit se produire avant d’utiliser cette fonction.
WSAENETDOWN
Le sous-système réseau a échoué.
WSAEACCES
L’adresse demandée est une adresse de diffusion, mais l’indicateur approprié n’a pas été défini. Appelez setsockopt avec le paramètre SO_BROADCAST pour autoriser l’utilisation de l’adresse de diffusion.
WSAEINVAL
Un indicateur inconnu a été spécifié ou MSG_OOB a été spécifié pour un socket avec SO_OOBINLINE activé.
WSAEINTR
Un appel Windows Sockets 1.1 bloquant a été annulé via WSACancelBlockingCall.
WSAEINPROGRESS
Un appel Windows Sockets 1.1 bloquant est en cours ou le fournisseur de services traite toujours une fonction de rappel.
WSAEFAULT
Les paramètres buf ou to ne font pas partie de l’espace d’adressage utilisateur, ou le paramètre tolen est trop petit.
WSAENETRESET
La connexion a été interrompue, car l'activité persistante a détecté un échec en cours d'opération.
WSAENOBUFS
Aucune zone tampon disponible.
WSAENOTCONN
Le socket n’est pas connecté (sockets orientés connexion uniquement).
WSAENOTSOCK
Le descripteur n’est pas un socket.
WSAEOPNOTSUPP
MSG_OOB a été spécifié, mais le socket n’est pas de type flux, comme le type SOCK_STREAM, les données OOB ne sont pas prises en charge dans le domaine de communication associé à ce socket, ou le socket est unidirectionnel et prend uniquement en charge les opérations de réception.
WSAESHUTDOWN
Le socket a été arrêté ; il n’est pas possible d’envoyer à sur un socket après l’appel de l’arrêt avec la valeur SD_SEND ou SD_BOTH.
WSAEWOULDBLOCK
Le socket est marqué comme non bloquant et l’opération demandée est bloquée.
WSAEMSGSIZE
Le socket est orienté message, et le message est supérieur à la valeur maximale prise en charge par le transport sous-jacent.
WSAEHOSTUNREACH
L’hôte distant n’est pas accessible à partir de cet hôte pour l’instant.
WSAECONNABORTED
Le circuit virtuel a été interrompu en raison d'un délai d'attente ou d'un autre échec. L’application doit fermer le socket, car il n’est plus utilisable.
WSAECONNRESET
Le circuit virtuel a été rétabli par la partie distante exécutant une fermeture brutale ou infructueuse. Pour les sockets UDP, l’hôte distant n’a pas pu remettre un datagramme UDP précédemment envoyé et a répondu avec un paquet ICMP « Port inaccessible ». L’application doit fermer le socket, car il n’est plus utilisable.
WSAEADDRNOTAVAIL
L’adresse distante n’est pas une adresse valide, par exemple, ADDR_ANY.
WSAEAFNOSUPPORT
Impossible d'utiliser les adresses figurant dans la famille spécifiée avec ce socket.
WSAEDESTADDRREQ
Une adresse de destination est requise.
WSAENETUNREACH
Le réseau ne peut pas être atteint à partir de cet hôte en ce moment.
WSAEHOSTUNREACH
Une opération de socket a été tentée sur un hôte impossible à atteindre.
WSAETIMEDOUT
La connexion a été supprimée, en raison d’une défaillance du réseau ou parce que le système à l’autre extrémité est tombé en panne sans préavis.

Remarques

La fonction sendto est utilisée pour écrire des données sortantes sur un socket. Pour les sockets orientés messages, vous devez veiller à ne pas dépasser la taille maximale des paquets des sous-réseaux sous-jacents, qui peut être obtenue à l’aide de getsockopt pour récupérer la valeur de l’option de socket SO_MAX_MSG_SIZE. Si les données sont trop longues pour être transmises atomiquement via le protocole sous-jacent, l’erreur WSAEMSGSIZE est retournée et aucune donnée n’est transmise.

Le paramètre to peut être n’importe quelle adresse valide dans la famille d’adresses du socket, y compris une adresse de diffusion ou de multidiffusion. Pour envoyer à une adresse de diffusion, une application doit avoir utilisé setsockopt avec SO_BROADCAST activé. Sinon, sendto échoue avec le code d’erreur WSAEACCES. Pour TCP/IP, une application peut envoyer à n’importe quelle adresse de multidiffusion (sans devenir membre du groupe).

Note Si un socket est ouvert, un appel setsockopt est effectué, puis un appel sendto est effectué, Windows Sockets effectue un appel de fonction de liaison implicite.
 
Si le socket n’est pas lié, des valeurs uniques sont affectées à l’association locale par le système, et le socket est alors marqué comme lié. Si le socket est connecté, la fonction getsockname peut être utilisée pour déterminer l’adresse IP locale et le port associés au socket.

Si le socket n’est pas connecté, le
La fonction getsockname peut être utilisée pour déterminer le numéro de port local associé au socket, mais l’adresse IP retournée est définie sur l’adresse générique pour le protocole donné (par exemple, INADDR_ANY ou « 0.0.0.0 » pour IPv4 et IN6ADDR_ANY_INIT ou « : : » pour IPv6).

L’achèvement réussi d’un sendto n’indique pas que les données ont été correctement remises.

La fonction sendto est normalement utilisée sur un socket sans connexion pour envoyer un datagramme à un socket homologue spécifique identifié par le paramètre to . Même si le socket sans connexion a été précédemment connecté à une adresse spécifique, le paramètre to remplace l’adresse de destination pour ce datagramme particulier uniquement. Sur un socket orienté connexion, les paramètres tolen et tolen sont ignorés, ce qui rend sendto équivalent à envoyer.

Note Lors de l’émission d’un appel Winsock bloquant tel que sendto, Winsock peut avoir besoin d’attendre un événement réseau avant que l’appel puisse se terminer. Winsock effectue une attente pouvant être alertée dans cette situation, qui peut être interrompue par un appel de procédure asynchrone (APC) planifié sur le même thread. L’émission d’un autre appel Winsock bloquant à l’intérieur d’un APC qui interrompt un appel Winsock bloquant en cours sur le même thread entraîne un comportement non défini et ne doit jamais être tenté par les clients Winsock.
 

Exemple de code

L’exemple suivant illustre l’utilisation de la fonction 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;
}


Pour les sockets utilisant l’adresse IP (version 4)

Pour envoyer une diffusion (sur un SOCK_DGRAM uniquement), l’adresse pointée par le paramètre to peut être construite pour contenir l’adresse IPv4 spéciale INADDR_BROADCAST (définie dans Winsock2.h), ainsi que le numéro de port prévu. Si l’adresse pointée par le paramètre to contient l’adresse INADDR_BROADCAST et le port prévu, la diffusion est envoyée sur toutes les interfaces vers ce port.

Si la diffusion doit être envoyée uniquement sur une interface spécifique, l’adresse pointée par le paramètre to doit contenir l’adresse de diffusion de sous-réseau pour l’interface et le port prévu. Par exemple, une adresse réseau IPv4 de 192.168.1.0 avec un masque de sous-réseau 255.255.255.0 utilise une adresse de diffusion de sous-réseau de 192.168.1.255.

Il est généralement déconseillé pour un datagramme de diffusion de dépasser la taille à laquelle la fragmentation peut se produire, ce qui implique que la partie données du datagramme (à l’exclusion des en-têtes) ne doit pas dépasser 512 octets.

Si aucun espace de mémoire tampon n’est disponible dans le système de transport pour contenir les données à transmettre, sendto se bloque, sauf si le socket a été placé en mode non bloquant. Sur les sockets orientés flux non bloquants, le nombre d’octets écrits peut être compris entre 1 et la longueur demandée, en fonction de la disponibilité de la mémoire tampon sur les systèmes client et serveur. La fonction select, WSAsyncSelect ou WSAEventSelect peut être utilisée pour déterminer quand il est possible d’envoyer plus de données.

L’appel de sendto avec une len de zéro est autorisé et retourne zéro comme valeur valide. Pour les sockets orientés message, un datagramme de transport de longueur nulle est envoyé.

Le paramètre flags peut être utilisé pour influencer le comportement de l’appel de fonction au-delà des options spécifiées pour le socket associé. La sémantique de cette fonction est déterminée par les options de socket et le paramètre flags . Ce dernier est construit à l’aide de l’opérateur OR au niveau du bit avec l’une des valeurs suivantes.

Valeur Signification
MSG_DONTROUTE Spécifie que les données ne doivent pas faire l’objet d’un routage. Un fournisseur de services Windows Sockets peut choisir d’ignorer cet indicateur.
MSG_OOB Envoie des données OOB (socket de type flux comme SOCK_STREAM uniquement).
 

Windows Phone 8 : cette fonction est prise en charge pour les applications Windows Phone Store sur Windows Phone 8 et versions ultérieures.

Windows 8.1 et Windows Server 2012 R2 : cette fonction est prise en charge pour les applications du Windows Store sur Windows 8.1, Windows Server 2012 R2 et versions ultérieures.

Configuration requise

   
Client minimal pris en charge Windows 8.1, Windows Vista [applications de bureau | Applications UWP]
Serveur minimal pris en charge Windows Server 2003 [applications de bureau | applications UWP]
Plateforme cible Windows
En-tête winsock.h (inclure Winsock2.h)
Bibliothèque Ws2_32.lib
DLL Ws2_32.dll

Voir aussi

WSAAsyncSelect

WSAEventSelect

Winsock Functions

Référence Winsock

Recv

recvfrom

select

envoyer

socket