web-dev-qa-db-fra.com

Obtenir le nombre d'octets disponibles dans socket par 'recv' avec 'MSG_PEEK' en C++

C++ a la fonction suivante pour recevoir des octets d'une socket, il peut vérifier le nombre d'octets disponibles avec l'indicateur MSG_PEEK. Avec MSG_PEEK, la valeur renvoyée de 'recv' est le nombre d'octets disponibles dans le socket:

#include <sys/socket.h>
ssize_t recv(int socket, void *buffer, size_t length, int flags); 

J'ai besoin d'obtenir le nombre d'octets disponibles dans le socket sans créer buffer (sans allouer de mémoire pour buffer). Est-ce possible et comment?

12
jondinham

Vous recherchez est ioctl(fd,FIONREAD,&bytes_available), et sous windows ioctlsocket(socket,FIONREAD,&bytes_available).

Soyez averti cependant, le système d'exploitation ne garantit pas nécessairement la quantité de données qu'il va mettre en mémoire tampon. Par conséquent, si vous attendez beaucoup de données, vous ferez mieux de lire les données dès leur arrivée et de les stocker dans votre propre mémoire tampon. jusqu'à ce que vous ayez tout ce dont vous avez besoin pour traiter quelque chose.

Pour ce faire, vous devez normalement lire des morceaux à la fois, tels que

char buf[4096];
ssize_t bytes_read;
do {
     bytes_read = recv(socket, buf, sizeof(buf), 0);
     if (bytes_read > 0) {
         /* do something with buf, such as append it to a larger buffer or
          * process it */
     }
} while (bytes_read > 0);

Et si vous ne voulez pas rester là à attendre des données, vous devriez vous tourner vers select ou epoll pour déterminer quand les données sont prêtes à être lues ou non, et l'indicateur O_NONBLOCK pour les sockets est très pratique si vous voulez vous assurer de ne jamais bloquer sur une recv.

29
hexist

Sous Windows, vous pouvez utiliser la fonction ioctlsocket() avec l'indicateur FIONREAD pour demander au socket le nombre d'octets disponibles sans avoir à lire/afficher les octets réels. La valeur renvoyée correspond au nombre minimal d'octets que recv() peut renvoyer sans blocage. Au moment où vous appelez réellement recv(), il se peut que davantage d'octets soient arrivés.

1
Remy Lebeau