Linux - ioctl avec FIONREAD toujours 0
J'essaie de savoir combien d'octets il y a lisible à mon socket TCP. Je fais appel ioctl avec le Drapeau "FIONREAD" qui devrait en fait de me donner cette valeur.
Lorsque j'appelle la fonction-je obtenir que le retour de val 0 ( donc pas d'Erreur ), mais aussi mon argument entier obtient la valeur 0. Ce serait pas un problème, mais lorsque j'appelle le recv() méthode que j'ai effectivement lu quelques Octets de la prise. Ce que je fais mal?
//ici, un peu de Code:
char recBuffer[BUFFERLENGTH] = {0};
int bytesAv = 0;
int bytesRead = 0;
int flags = 0;
if ( ioctl (m_Socket,FIONREAD,&bytesAv) < 0 )
{
//Error
}
if ( bytesAv < 1 )
{
//No Data Available
}
bytesRead = recv(m_Socket,recBuffer,BUFFERLENGTH,flags);
Lorsque j'appelle la fonction recv je acutally lire certaines Données valides ( je m'y attendais )
OriginalL'auteur Toby | 2011-08-08
Vous devez vous connecter pour publier un commentaire.
Ça se passe très rapidement, c'est pourquoi vous ne voyez pas de quoi que ce soit. Ce que vous faites:
ioctl
: Est-il données pour moi ? Non, rien encorerecv
: Bloc jusqu'à ce qu'il y a des données pour moi. Certains (court) temps plus tard: Voici vos donnéesDonc, si vous voulez vraiment voir
FIONREAD
, il suffit d'attendre.Hey, je suis le seul à lui remettre l'arme :-))
Œuvres! Merci!!!! A fonctionné, même sans la boucle ( juste lui donner le temps d'obtenir les données ^^ ) Mais j'ai un autre interrogatio maintenant...
Que vous vraiment besoin de lok dans
select(2)
.Je me demandais, pourquoi personne ne m'a suggéré d'utiliser poll() ou epoll(). Et après que d'essayer d'obtenir la taille des données disponibles pour la lecture.
OriginalL'auteur cnicutar
La réponse réelle ici est d'utiliser select(2) comme cnicutar dit. Toby, ce que vous ne pas comprendre, c'est que vous avez une condition de course. D'abord, vous regardez la douille et de se demander combien d'octets sont là. Puis, alors que votre code est le traitement de l' "pas de données" bloc d'octets reçus par le matériel & OS asynchrone à votre demande. Donc, une fois que la fonction recv() est appelée, la réponse de "non-octets sont disponibles" n'est plus vrai...
Sûr, un petit sommeil probablement résolu votre programme il y a deux ans, mais il a également enseigné terrible pratique de codage, et que vous avez perdu une occasion d'apprendre à utiliser des sockets correctement à l'aide de select().
De plus, comme Karoly Horvath dit, vous pouvez dire recv de ne pas lire plus d'octets que vous pouvez stocker dans la mémoire tampon que l'utilisateur est passé en. Ensuite, votre interface de la fonction devient "Ce fn sera de retour que le nombre d'octets disponibles sur le socket, mais pas plus de [taille de la mémoire tampon que vous avez passé dans]".
Cela signifie que cette fonction n'a pas besoin de s'inquiéter sur l'effacement de la mémoire tampon. L'appelant peut appeler votre fonction autant de fois que nécessaire pour effacer tous les octets (ou vous pouvez fournir un distinct fn supprime les données de gros et de n'attacher qu'une fonctionnalité spécifique de recueillir des données de fonction). Votre fonction est plus souple en ne faisant pas trop de choses. Vous pouvez ensuite créer une fonction wrapper qui est smart à vos besoins de transfert de données d'une application particulière, et que le fn appelle la get_data fn et la clear_socket fn comme nécessaire pour une application spécifique. Maintenant, vous êtes la construction d'une bibliothèque, vous pouvez porter autour du projet, et peut-être un emploi à l'autre si vous avez de la chance d'avoir un employeur qui vous permet de prendre de code avec vous.
OriginalL'auteur Tim
Utiliser select (), puis ioctl(FIONREAD) puis recv()
OriginalL'auteur brian beuning
Vous faites rien de mal, si vous êtes à l'aide de blocage I/O recv() bloque jusqu'à ce que les données sont disponibles.
quelques lignes plus tôt? Ne vous attendez une réponse immédiate? Cela n'arrivera pas. Mettre un y dormir ou faire select/poll/epoll/kqueue sur le socket, et l'appel ioctl sera très bien. Pourquoi voulez-vous faire appel de toute façon?
En fait je viens de penser que trop vais essayer avec un peu de sommeil entre la commande et l'ioctl
Je ne sais toujours pas pourquoi voulez-vous faire que l'appel ioctl. quel est le point?
L'utilisation de sélectionner ou de sondage... et je n'ai aucune idée de ce qu'entendez-vous par chasse d'eau.
OriginalL'auteur Karoly Horvath