web-dev-qa-db-fra.com

Comment vérifier la quantité de données disponibles pour un socket en C et Linux

J'ai un serveur qui reçoit un flux continu de données. Plutôt que de lire plusieurs fois depuis un socket, j'aimerais lire toutes les données dans le tampon de réception de socket avec un appel système à read().

Bien sûr, je peux passer un tampon important et read() essaiera de le remplir avec toutes les données disponibles. Mais cela gaspillerait beaucoup de mémoire car la plupart du temps, le tampon mallocé serait plus volumineux que les données réelles disponibles sur le socket. Existe-t-il un moyen d'interroger les données disponibles sur un socket?

28
Jimm

Oui:

#include <sys/ioctl.h>

...

int count;
ioctl(fd, FIONREAD, &count);
50
fizzer

Non, il n'y en a pas. Même s'il existait un moyen de le faire, toute réponse que vous obtiendriez serait immédiatement obsolète (car de nouvelles données peuvent arriver à tout moment).

Notez que lorsque vous passez un tampon à read(), la fonction retournera quand il y aura toute quantité de données à lire (au moins un octet), au lieu d'attendre que le tampon se remplisse complètement.

4
Greg Hewgill

Ceci est une "sorte de" réponse: recv(char* buffer, size_t nytes, int flags) où flags est OU avec:

MSG_PEEK
This flag causes the receive operation to return data from the beginning of the receive queue without removing that data from the queue. Thus, a subsequent receive call will return the same data.

De telle sorte que vous puissiez voir si un nombre arbitraire d'octets existe dans le tampon, sans lire de manière irréversible le tampon. C'est une demi-réponse car ce n'est pas la manière la plus efficace de le faire, et MSG_PEEK est généralement utilisé lorsque les messages ont des en-têtes de longueur connue, comme ceci:

000123DT001    

00123 est la longueur de l'ensemble du message, y compris l'en-tête, DT est le type du message et 001 est le nombre de tentatives effectuées par l'expéditeur. L'idée est que vous pouvez extraire quelque chose qui vous dit combien d'octets lisent complètement un message. Vous n'êtes pas intéressé par les messages. Mais c’est la raison derrière MSG_PEEK

2
jim mcnamara

Vous devez essayer d’envoyer et recevoir des commandes, de même que vous êtes capable de lire et d’écrire dans une socket, caractère par caractère, pour ne pas gaspiller de mémoire et améliorer la communication.

2
ravi bhuva

Vous pouvez utiliser Des sockets non bloquants , ou sélectionner ()/poll () d'ailleurs Je préfère les sockets non bloquants car je peux faire d'autres choses en attendant de nouvelles données.

1
yeyo

je pense que vous essayez d’obtenir de nombreux paquets avec un seul appel système pour réduire le temps système dû aux appels système.

vous pouvez donc essayer les interfaces PACKET sockets pour les noyaux Linux 2.4 ou 2.6 + essayez ceci http://lxr.free-electrons.com/source/Documentation/networking/packet_mmap.txt

0
akp