send, fonction (winsock2.h)
La fonction d’envoi envoie des données sur un socket connecté.
Syntaxe
int WSAAPI send(
[in] SOCKET s,
[in] const char *buf,
[in] int len,
[in] int flags
);
Paramètres
[in] s
Descripteur identifiant un socket connecté.
[in] buf
Pointeur vers une mémoire tampon contenant les données à transmettre.
[in] len
Longueur, en octets, des données dans la mémoire tampon pointées par le paramètre buf .
[in] flags
Ensemble d’indicateurs qui spécifient la façon dont l’appel est effectué. Ce paramètre est construit à l’aide de l’opérateur OR au niveau du bit avec l’une des valeurs suivantes.
Valeur retournée
Si aucune erreur ne se produit, send retourne le nombre total d’octets envoyés, qui peut être inférieur au nombre demandé à envoyer dans le paramètre 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 l’option de socket SO_BROADCAST pour permettre l’utilisation de l’adresse de diffusion. | |
Un appel bloquant Windows Sockets 1.1 a été annulé via WSACancelBlockingCall. | |
Un appel bloquant Windows Sockets 1.1 est en cours ou le fournisseur de services traite toujours une fonction de rappel. | |
Le paramètre buf n’est pas entièrement contenu dans une partie valide de l’espace d’adressage utilisateur. | |
La connexion a été interrompue en raison du maintien d'activité ayant détecté un échec lorsque l'opération était en cours. | |
Aucune zone tampon disponible. | |
Le socket n'est pas connecté. | |
Le descripteur n’est pas un socket. | |
MSG_OOB a été spécifié, mais le socket n’est pas de type flux tel que 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 ne prend en charge que les opérations de réception. | |
Le socket a été arrêté ; il n’est pas possible d’envoyer sur un socket une fois l’arrêt appelé avec la valeur définie sur 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 plus grand que le maximum pris en charge par le transport sous-jacent. | |
L’hôte distant n’est pas accessible à partir de cet hôte pour le moment. | |
Le socket n’a pas été lié à bind, ou un indicateur inconnu a été spécifié, ou MSG_OOB a été spécifié pour un socket avec SO_OOBINLINE activé. | |
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. | |
La connexion a été supprimée, en raison d’une défaillance réseau ou parce que le système à l’autre extrémité a été arrêté sans préavis. |
Remarques
La fonction d’envoi est utilisée pour écrire des données sortantes sur un socket connecté.
Pour les sockets orientés message (famille d’adresses de AF_INET ou de AF_INET6, type de SOCK_DGRAM et protocole d’IPPROTO_UDP, par exemple), veillez à ne pas dépasser la taille de paquet maximale du fournisseur sous-jacent. La taille maximale du paquet de messages d’un fournisseur peut être obtenue en appelant getsockopt avec le paramètre optname défini sur SO_MAX_MSG_SIZE pour récupérer la valeur de l’option de socket. Si les données sont trop longues pour passer de manière atomique via le protocole sous-jacent, l’erreur WSAEMSGSIZE est retournée et aucune donnée n’est transmise.
La réussite d’une fonction d’envoi n’indique pas que les données ont été correctement remises et reçues au destinataire. Cette fonction indique uniquement que les données ont été correctement envoyées.
Si aucun espace tampon n’est disponible dans le système de transport pour contenir les données à transmettre, l’envoi est bloqué, 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 ordinateurs clients et serveurs. Les fonctions select, WSAAsyncSelect ou WSAEventSelect peuvent être utilisées pour déterminer quand il est possible d’envoyer plus de données.
L’appel de l’envoi avec un paramètre len de zéro est autorisé et sera traité par les implémentations comme réussie. Dans ce cas, l’envoi 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 la fonction au-delà des options spécifiées pour le socket associé. La sémantique de la fonction d’envoi est déterminée par toutes les options précédemment définies sur le socket spécifié dans le paramètre s et le paramètre flags passé à la fonction d’envoi .
L’ordre des appels à envoyer est également l’ordre dans lequel les mémoires tampons sont transmises à la couche de transport. l’envoi ne doit pas être appelé simultanément sur le même socket orienté flux à partir de différents threads, car certains fournisseurs Winsock peuvent fractionner une demande d’envoi volumineuse en plusieurs transmissions, ce qui peut entraîner l’interlacement involontaire de données à partir de plusieurs demandes d’envoi simultanées sur le même socket orienté flux.
Exemple de code
L’exemple suivant illustre l’utilisation de la fonction send .#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")
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT 27015
int main() {
//----------------------
// Declare and initialize variables.
int iResult;
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct sockaddr_in clientService;
int recvbuflen = DEFAULT_BUFLEN;
char *sendbuf = "Client: sending data test";
char recvbuf[DEFAULT_BUFLEN] = "";
//----------------------
// 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 connecting to server
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ConnectSocket == INVALID_SOCKET) {
wprintf(L"socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
//----------------------
// The sockaddr_in structure specifies the address family,
// IP address, and port of the server to be connected to.
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr( "127.0.0.1" );
clientService.sin_port = htons( DEFAULT_PORT );
//----------------------
// Connect to server.
iResult = connect( ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService) );
if (iResult == SOCKET_ERROR) {
wprintf(L"connect failed with error: %d\n", WSAGetLastError() );
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
//----------------------
// Send an initial buffer
iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
if (iResult == SOCKET_ERROR) {
wprintf(L"send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
printf("Bytes Sent: %d\n", iResult);
// shutdown the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
wprintf(L"shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
// Receive until the peer closes the connection
do {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if ( iResult > 0 )
wprintf(L"Bytes received: %d\n", iResult);
else if ( iResult == 0 )
wprintf(L"Connection closed\n");
else
wprintf(L"recv failed with error: %d\n", WSAGetLastError());
} while( iResult > 0 );
// close the socket
iResult = closesocket(ConnectSocket);
if (iResult == SOCKET_ERROR) {
wprintf(L"close failed with error: %d\n", WSAGetLastError());
WSACleanup();
return 1;
}
WSACleanup();
return 0;
}
Exemple de code
Pour obtenir un autre exemple qui utilise la fonction d’envoi, consultez Prise en main Avec Winsock.Remarques pour les sockets IrDA
- Le fichier d’en-tête Af_irda.h doit être inclus explicitement.
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
Condition requise | Valeur |
---|---|
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 | winsock2.h |
Bibliothèque | Ws2_32.lib |
DLL | Ws2_32.dll |