recevoir du socket local unix et de la taille du tampon

J’ai un problème avec les sockets locaux Unix. En lisant un message plus long que la taille de la mémoire tampon temporaire, la demande est trop longue (peut-être indéfiniment).

Ajouté après quelques tests: il y a toujours un problème avec freeze at :: recv. quand j’envoie (1023 * 8) octets ou moins à la prise UNIX – tout est ok, mais quand envoyé plus de (1023 * 9) – je me bloque sur la commande recv. peut-être ses parameters de socket UNIX par défaut de FreeBSD ou les parameters de socket par défaut de C ++? Qui sait?


J’ai fait quelques tests supplémentaires et je suis sûr à 100% que son “blocage” sur la dernière 9ème itération lors de l’exécution de la commande :: recv, lors de la tentative de lecture du message> = (1023 * 9) octets de long. (premier 8ème itération se passe bien.)

Ce que je fais: L’idée est de lire dans une boucle do / while depuis un socket avec

::recv (current_socket, buf, 1024, 0); 

et vérifiez buf pour un symbole spécial. Si non trouvé:

  1. fusionner le contenu du tampon à ssortingngxxx += buf;
  2. bzero temp buf
  3. continuez la boucle :: recv

Comment est-ce que je corrige le problème avec la demande prenant trop de temps dans la boucle while?

Existe-t-il un meilleur moyen d’effacer le tampon? Actuellement, c’est:

  char buf [1025]; bzero(buf, 1025); 

Mais je sais que bzero est obsolète dans le nouveau standard c ++.

EDIT: * “Pourquoi faut-il nettoyer le tampon *

Je vois des questions aux commentaires avec cette question. Sans nettoyage du tampon lors de la prochaine (dernière) itération de lecture dans le tampon, celui-ci contiendra la “queue” de la première partie du message.

Exemple:

  // message at the socket is "AAAAAACDE" char buf [6]; ::recv (current_socket, buf, 6, 0); // read 6 symbols, buf = "AAAAAA" // no cleanup, read the last part of the message with recv ::recv (current_socket, buf, 6, 0); // read 6 symbols, but buffer contain only 3 not readed before symbols, therefore // buf now contain "CDEAAA" (not correct, we waiting for CDE only) 

Lorsque votre recv() entre dans une boucle infinie, cela signifie probablement qu’elle ne progresse pas du tout sur les itérations (c’est-à-dire que vous obtenez toujours une lecture rapide de la taille zéro immédiatement, donc votre boucle ne se ferme jamais, car vous n’êtes pas obtenir des données). Pour les sockets de stream, un recv() de taille zéro signifie que l’extrémité distante est déconnectée (c’est quelque chose comme read() provenant d’un fichier lorsque l’entrée est positionnée sur EOF et que vous avez zéro octet), ou du moins qu’il se ferme le canal d’envoi (pour TCP en particulier).

Vérifiez si votre script PHP envoie réellement la quantité de données que vous prétendez envoyer.

Pour append un petit exemple (non sensible) pour utiliser correctement recv () dans une boucle:

 char buf[1024]; std::ssortingng data; while( data.size() < 10000 ) { // what you wish to receive ::ssize_t rcvd = ::recv(fd, buf, sizeof(buf), 0); if( rcvd < 0 ) { std::cout << "Failed to receive\n"; // Receive failed - something broke, see errno. std::abort(); } else if( !rcvd ) { break; // No data to receive, remote end closed connection, so quit. } else { data.append(buf, rcvd); // Received into buffer, attach to data buffer. } } if( data.size() < 10000 ) { std::cout << "Short receive, sender broken\n"; std::abort(); } // Do something with the buffer data. 

Au lieu de bzero , vous pouvez simplement utiliser

 memset(buf, 0, 1025); 

Ce sont deux problèmes distincts. Le temps long est probablement une boucle infinie due à un bogue dans votre code et n’a rien à voir avec la façon dont vous effacez votre tampon. En fait, vous ne devriez pas avoir besoin de vider le tampon; receive renvoie le nombre d’octets lus, vous pouvez donc parsingr le tampon de votre SPECIAL_SYMBOL jusqu’à ce point.

Si vous collez le code, je peux peut-être vous aider. plus.

Juste pour clarifier: bzero n’est pas obsolète en C ++ 11. Au contraire, il ne fait jamais partie d’ aucune norme C ou C ++. C a commencé avec memset il y a plus de 20 ans. Pour C ++, vous pouvez utiliser plutôt std::fill_n (ou simplement utiliser std::vector , qui peut être rempli automatiquement). Là encore, je ne suis pas sûr qu’il y ait une bonne raison de remplir le tampon à zéro dans ce cas.