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 |
---|---|
Un appel WSAStartup réussi doit se produire avant d’utiliser cette fonction. | |
Le sous-système réseau a échoué. | |
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. | |
Un indicateur inconnu a été spécifié ou MSG_OOB a été spécifié pour un socket avec SO_OOBINLINE activé. | |
Un appel Windows Sockets 1.1 bloquant a été annulé via WSACancelBlockingCall. | |
Un appel Windows Sockets 1.1 bloquant est en cours ou le fournisseur de services traite toujours une fonction de rappel. | |
Les paramètres buf ou to ne font pas partie de l’espace d’adressage utilisateur, ou le paramètre tolen est trop petit. | |
La connexion a été interrompue, car l'activité persistante a détecté un échec en cours d'opération. | |
Aucune zone tampon disponible. | |
Le socket n’est pas connecté (sockets orientés connexion uniquement). | |
Le descripteur n’est pas un socket. | |
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. | |
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. | |
Le socket est marqué comme non bloquant et l’opération demandée est bloquée. | |
Le socket est orienté message, et le message est supérieur à la valeur maximale prise en charge par le transport sous-jacent. | |
L’hôte distant n’est pas accessible à partir de cet hôte pour l’instant. | |
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. | |
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. | |
L’adresse distante n’est pas une adresse valide, par exemple, ADDR_ANY. | |
Impossible d'utiliser les adresses figurant dans la famille spécifiée avec ce socket. | |
Une adresse de destination est requise. | |
Le réseau ne peut pas être atteint à partir de cet hôte en ce moment. | |
Une opération de socket a été tentée sur un hôte impossible à atteindre. | |
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).
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.
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 |