Partager via


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 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 tel que SOCK_STREAM uniquement).

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
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 l’option de socket SO_BROADCAST pour permettre l’utilisation de l’adresse de diffusion.
WSAEINTR
Un appel bloquant Windows Sockets 1.1 a été annulé via WSACancelBlockingCall.
WSAEINPROGRESS
Un appel bloquant Windows Sockets 1.1 est en cours ou le fournisseur de services traite toujours une fonction de rappel.
WSAEFAULT
Le paramètre buf n’est pas entièrement contenu dans une partie valide de l’espace d’adressage utilisateur.
WSAENETRESET
La connexion a été interrompue en raison du maintien d'activité ayant détecté un échec lorsque l'opération était en cours.
WSAENOBUFS
Aucune zone tampon disponible.
WSAENOTCONN
Le socket n'est pas connecté.
WSAENOTSOCK
Le descripteur n’est pas un socket.
WSAEOPNOTSUPP
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.
WSAESHUTDOWN
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.
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 plus grand que le maximum pris en charge par le transport sous-jacent.
WSAEHOSTUNREACH
L’hôte distant n’est pas accessible à partir de cet hôte pour le moment.
WSAEINVAL
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é.
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.
WSAETIMEDOUT
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.

Note Lors de l’émission d’un appel Winsock bloquant tel que l’envoi, Winsock peut avoir besoin d’attendre qu’un événement réseau puisse se terminer. Winsock effectue une attente alertable 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 a interrompu 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 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 Phone 8 : cette fonction est prise en charge pour les applications du Store Windows Phone 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

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

Voir aussi

Prise en main avec Winsock

WSAAsyncSelect

WSAEventSelect

Winsock Functions

Référence Winsock

Recv

recvfrom

select

Sendto

socket