recvfrom, fonction (winsock2.h)
La fonction recvfrom reçoit un datagramme et stocke l’adresse source.
Syntaxe
int WSAAPI recvfrom(
[in] SOCKET s,
[out] char *buf,
[in] int len,
[in] int flags,
[out] sockaddr *from,
[in, out, optional] int *fromlen
);
Paramètres
[in] s
Descripteur identifiant un socket lié.
[out] buf
Mémoire tampon pour les données entrantes.
[in] len
Longueur, en octets, de la mémoire tampon pointée vers le paramètre buf .
[in] flags
Ensemble d’options qui modifient le comportement de l’appel de fonction au-delà des options spécifiées pour le socket associé. Pour plus d’informations, consultez les remarques ci-dessous.
[out] from
Pointeur facultatif vers une mémoire tampon dans une structure de sockaddr qui contiendra l’adresse source au retour.
[in, out, optional] fromlen
Pointeur facultatif vers la taille, en octets, de la mémoire tampon pointée vers le paramètre from .
Valeur retournée
Si aucune erreur ne se produit, recvfrom retourne le nombre d’octets reçus. Si la connexion a été correctement fermée, la valeur de retour est zéro. 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é. | |
La mémoire tampon pointée vers par le buf ou à partir des paramètres ne se trouvent pas dans l’espace d’adressage de l’utilisateur, ou le paramètre fromlen est trop petit pour prendre en charge l’adresse source de l’adresse de l’homologue. | |
L’appel (bloquant) 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 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é, ou (pour les sockets de type flux d’octets uniquement) len était zéro ou négatif. | |
Le socket est connecté. Cette fonction n’est pas autorisée avec un socket connecté, que le socket soit orienté connexion ou sans connexion. | |
Pour un socket datagramme, cette erreur indique que la durée de vie (TTL, Time to Live) a expiré. | |
Le descripteur dans le paramètre s 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 prend uniquement en charge les opérations d’envoi. | |
Le socket a été arrêté ; il n’est pas possible de se rétracter sur un socket après l’arrêt avec la définition de SD_RECEIVE ou de SD_BOTH. | |
Le socket est marqué comme non bloquant et l’opération de récupération est bloquée. | |
Le message était trop volumineux pour tenir dans la mémoire tampon pointée par le paramètre buf et a été tronqué. | |
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. | |
Le circuit virtuel a été rétabli par la partie distante exécutant une fermeture brutale ou infructueuse. L’application doit fermer le socket ; il n’est plus utilisable. Sur un socket de datagramme UDP, cette erreur indique qu’une opération d’envoi précédente a donné lieu à un message ICMP Port inaccessible . |
Remarques
La fonction recvfrom lit les données entrantes sur les sockets connectés et non connectés et capture l’adresse à partir de laquelle les données ont été envoyées. Cette fonction est généralement utilisée avec des sockets sans connexion. L’adresse locale du socket doit être connue. Pour les applications serveur, cela se fait généralement explicitement par le biais de la liaison. La liaison explicite est déconseillée pour les applications clientes. Pour les applications clientes utilisant cette fonction, le socket peut devenir implicitement lié à une adresse locale via sendto, WSASendTo ou WSAJoinLeaf.
Pour les sockets orientés flux tels que ceux de type SOCK_STREAM, un appel à la récupération retourne autant d’informations que ce qui est actuellement disponible, jusqu’à la taille de la mémoire tampon spécifiée. Si le socket a été configuré pour la réception inline des données OOB (option socket SO_OOBINLINE) et que les données OOB ne sont pas encore lues, seules les données OOB sont retournées. L’application peut utiliser la commande ioctlsocket ou WSAIoctlSIOCATMARK pour déterminer si d’autres données OOB restent à lire. Les paramètres from et fromlen sont ignorés pour les sockets orientés connexion.
Pour les sockets orientés message, les données sont extraites du premier message en file d’attente, jusqu’à la taille de la mémoire tampon spécifiée. Si le datagramme ou le message est plus grand que la mémoire tampon spécifiée, la mémoire tampon est remplie avec la première partie du datagramme et la récurrence génère l’erreur WSAEMSGSIZE. Pour les protocoles non fiables (par exemple, UDP), les données excédentaires sont perdues. Pour UDP si le paquet reçu ne contient aucune donnée (vide), la valeur de retour de la fonction recvfrom est zéro.
Si le paramètre from est différent de zéro et que le socket n’est pas orienté connexion (type SOCK_DGRAM par exemple), l’adresse réseau de l’homologue qui a envoyé les données est copiée dans la structure sockaddr correspondante. La valeur pointée par fromlen est initialisée à la taille de cette structure et est modifiée, au retour, pour indiquer la taille réelle de l’adresse stockée dans la structure sockaddr .
Si aucune donnée entrante n’est disponible au niveau du socket, la fonction recvfrom bloque et attend que les données arrivent conformément aux règles de blocage définies pour WSARecv avec l’indicateur MSG_PARTIAL non défini, sauf si le socket n’est pas bloquant. Dans ce cas, une valeur de SOCKET_ERROR est retournée avec le code d’erreur défini sur WSAEWOULDBLOCK. Le select, WSAAsyncSelect ou WSAEventSelect peut être utilisé pour déterminer quand d’autres données arrivent.
Si le socket est orienté connexion et que le côté distant a arrêté la connexion correctement, l’appel à revfrom se termine immédiatement avec zéro octet reçu. Si la connexion a été réinitialisée , la récurrence échoue avec l’erreur WSAECONNRESET.
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_PEEK | Examine les données entrantes. Les données sont copiées dans la mémoire tampon, mais ne sont pas supprimées de la file d’attente d’entrée. |
MSG_OOB | Traite les données hors bande (OOB). |
Exemple de code
L’exemple suivant illustre l’utilisation de la fonction recvfrom .#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 = 0;
WSADATA wsaData;
SOCKET RecvSocket;
sockaddr_in RecvAddr;
unsigned short Port = 27015;
char RecvBuf[1024];
int BufLen = 1024;
sockaddr_in SenderAddr;
int SenderAddrSize = sizeof (SenderAddr);
//-----------------------------------------------
// 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 receiver socket to receive datagrams
RecvSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (RecvSocket == INVALID_SOCKET) {
wprintf(L"socket failed with error %d\n", WSAGetLastError());
return 1;
}
//-----------------------------------------------
// Bind the socket to any address and the specified port.
RecvAddr.sin_family = AF_INET;
RecvAddr.sin_port = htons(Port);
RecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
iResult = bind(RecvSocket, (SOCKADDR *) & RecvAddr, sizeof (RecvAddr));
if (iResult != 0) {
wprintf(L"bind failed with error %d\n", WSAGetLastError());
return 1;
}
//-----------------------------------------------
// Call the recvfrom function to receive datagrams
// on the bound socket.
wprintf(L"Receiving datagrams...\n");
iResult = recvfrom(RecvSocket,
RecvBuf, BufLen, 0, (SOCKADDR *) & SenderAddr, &SenderAddrSize);
if (iResult == SOCKET_ERROR) {
wprintf(L"recvfrom failed with error %d\n", WSAGetLastError());
}
//-----------------------------------------------
// Close the socket when finished receiving datagrams
wprintf(L"Finished receiving. Closing socket.\n");
iResult = closesocket(RecvSocket);
if (iResult == SOCKET_ERROR) {
wprintf(L"closesocket failed with error %d\n", WSAGetLastError());
return 1;
}
//-----------------------------------------------
// Clean up and exit.
wprintf(L"Exiting.\n");
WSACleanup();
return 0;
}
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 (inclure Winsock2.h) |
Bibliothèque | Ws2_32.lib |
DLL | Ws2_32.dll |