send () ne pas livrer tous les octets?

Pourquoi send() dans winsock garantit-il pas la livraison de tous les octets que vous demandez?

C’est TCP et ça bloque les sockets.

De même, cela se produit lorsque vous ne bloquez pas. Comment pouvez-vous garantir que vous envoyez tout?

J’ai remarqué que recv() fait la même chose.

S’il n’a pas tout envoyé, il suffit d’appeler send nouveau sur le rest. Si vous bloquez, vous pouvez le faire immédiatement. Si vous ne bloquez pas, vous pouvez attendre ou utiliser une méthode de découverte de socket (comme les ports de select ou d’achèvement d’E / S). La même chose vaut pour recv . Si vous n’obtenez pas tout ce que vous voulez, appelez à nouveau recv C’est l’une des raisons pour lesquelles recv et send renvoient le nombre d’octets envoyés ou reçus.

Le nombre d’octets que vous transmettez pour l’ send ou la recv est juste une limite. Il peut envoyer moins que cela (cependant, à moins que non-bloquant, ne sera généralement pas). Mais il peut certainement recevoir moins que cela. (Le système d’exploitation n’a aucun contrôle sur la quantité de données qu’il reçoit ni sur le moment où il les reçoit.)

TCP est implémenté pour vous. Mais si vous avez un protocole d’application qui implique des messages au niveau de l’application, l’application doit les implémenter. Cela n’arrivera pas par magie. TCP ne “colle pas les octets ensemble” dans un message pour vous. TCP est un protocole de stream d’octets, pas un protocole de message. Si vous voulez des messages, vous devez les implémenter.

Ce comportement est “par conception”.

Vous pouvez utiliser une boucle externe comme indiqué dans cet exemple:

 int sendBuffer (SOCKET ClientSocket, const char *buf, int len, int flags) { int num_left = len; int num_sent; int err = 0; const char *cp = buf; while (num_left > 0) { num_sent = send(ClientSocket, cp, num_left, flags); if (num_sent < 0) { err = SOCKET_ERROR; break; } assert(num_sent <= num_left); num_left -= num_sent; cp += num_sent; } return (err == SOCKET_ERROR ? SOCKET_ERROR : len); } 

send vous indique ce qu’il a pu envoyer via sa valeur de retour. Boucle jusqu’à ce que send envoie cumulativement toutes les données ou renvoie une erreur.