getline sur une socket

Existe-t-il une fonction libc qui ferait la même chose que getline, mais fonctionnerait avec un socket connecté au lieu d’un stream FILE *?

Une solution de contournement serait d’appeler fdopen sur un socket. Quelles sont les choses qui devraient être sockets en charge, en le faisant. Quelles sont les raisons de le faire / ne pas le faire.

Une raison évidente de le faire est d’appeler getline et co, mais c’est peut-être une meilleure idée de réécrire une ligne personnalisée?

lorsque vous appelez une lecture sur un socket, elle peut renvoyer prématurément une valeur nulle. par exemple.

read(fd, buf, bufsize) 

peut renvoyer une valeur inférieure à bufsize si la mémoire tampon du kernel pour le socket tcp est saturée. dans un tel cas, il peut être nécessaire de rappeler la fonction de lecture à moins qu’elle ne renvoie un résultat nul ou négatif.

il est donc préférable d’éviter les fonctions stdio. vous devez créer des wrappers pour la fonction de lecture afin de mettre en œuvre l’appel itératif à lire pour obtenir des octets de taille de fichier de manière fiable. il ne doit renvoyer une valeur nulle que lorsque aucun autre octet ne peut être lu depuis le socket, comme si le fichier était en cours de lecture depuis le disque local.

vous pouvez trouver des enveloppes dans le livre Computer Systems: Perspective d’un programmeur de Randal Bryant.

Le code source est disponible sur ce site. recherchez les fonctions commençant par rio_.

Le problème serait que si le programme ne recevait pas la nouvelle ligne (\ n ou \ r \ n dépend de votre implémentation), le programme se bloquerait. J’écrirais votre propre version qui appelle également select () pour vérifier si le socket est toujours en lecture / écriture et qu’il n’y a pas d’erreur. En réalité, il n’y aurait aucun moyen de savoir si un autre “\ n” ou “\ r \ n” est imminent, assurez-vous donc que les données du client / serveur seront cohérentes.

Imaginez que vous avez codé un serveur Web qui lit les en-têtes à l’aide de getline (). Si un attaquant simple envoyé

 GET / HTTP/1.1\r\n This line isn't terminated: bla 

L’appel de la ligne téléphonique ne reviendrait jamais et le programme se bloquerait. Cela vous coûterait probablement des ressources et éventuellement un déni de service.

Si le socket est connecté à une entrée non fiable, préparez-vous à une entrée arbitraire dans un délai arbitraire.

  • \ 0 caractère avant \ r \ n
  • attendre éternellement pour \ r ou \ n
  • toute autre chose potentiellement laide

Une façon de traiter le minutage arbitraire et les données arbitraires serait de donner des délais d’attente pour les lectures, par exemple via select (2) et d’alimenter octet par octet les données que vous recevez réellement.