Y a-t-il un moyen de vérifier combien d'octets sont écrits dans un tampon au moment exact? Je voudrais définir dynamiquement la quantité de données que j'envoie via socket en utilisant socket.send(). Maintenant, j'ai un problème, disons que mon fichier fait 200 Ko et que mon tampon est défini sur 24 Ko, je dois donc envoyer 9 paquets et mon fichier de sortie fait 216 Ko et non 200 Ko en entrée. Existe-t-il un moyen de gérer ces octets vides?

-1
kapisolec 9 déc. 2020 à 16:25

2 réponses

Meilleure réponse

socket.send m'est inconnu. Je suppose que vous voulez dire en utilisant send (2) sur certains < a href = "https://man7.org/linux/man-pages/man7/socket.7.html" rel = "nofollow noreferrer"> socket (7) .

Dans de nombreux cas (pensez à un trafic tcp (7) passant par plusieurs routeurs Wifi), les paquets pourraient être fragmentés. Ainsi, un send (2) donné d'un côté pourrait correspondre à plusieurs recv (2) côté réception et vice versa.

Ensuite, vous devez gérer d'une manière ou d'une autre vos données de paquet (par exemple, compter et mettre en mémoire tampon les données émises et celles reçues). En pratique, vous aurez besoin de quelques conventions documentées à leur sujet. HTTP ou SMTP ou JSONRPC ou ONCRPC ou MQTT pourrait être une source d'inspiration.

Vous trouverez des bibliothèques qui pourraient être utiles. Par exemple. libcurl, Wt, Qt, POCO, libonion. Ils sont open source, vous êtes donc autorisé à étudier leur code source.

Vous pouvez également étudier le code source de serveurs open source bien connus, tels que lighttpd, postfix, etc ...

Vous avez tagué votre question à la fois C et C++, mais ce sont des langues très différentes. Consultez cette référence pour en savoir plus.

Existe-t-il un moyen de vérifier combien de données / octets sont écrits dans le tampon en C

Oui, car send (2) et write (2) (et aussi recv (2) et read (2)) renvoient un nombre d'octets en cas de succès.

Votre boucle d’événements les gérera (comptage des octets, gestion des tampons) et utilisera poll (2) ou un autre appel système de multiplexage. Vous pourriez trouver des bibliothèques utiles dans ce cas (libev, libevent, etc ...)

0
Basile Starynkevitch 9 déc. 2020 à 13:48

La meilleure chose à faire est de garder vous-même un compte de ces octets, car vous savez toujours combien d'octets vous écrivez.

Si vous avez 200 Ko à envoyer et que vous pouvez envoyer 24 Ko à la fois, c'est juste (en pseudocode):

const int chunkSize = 24*1024;
const int inputSize = 200*1024;

char input[inputSize];   // N.B. VLAs not actually valid C++; this is pseudo-code
int bytesSent = 0;

while (true)
{
   const int bytesRemaining = inputSize - bytesSent;
   const int bytesToSend = std::min(chunkSize, bytesRemaining);
   
   if (bytesToSend == 0)
   {
      // Done!
      break;
   }
   
   const int bytesWritten = send(&input[bytesSent], bytesToSend);
   
   if (bytesWritten == 0)  // I'm assuming 0 written means error; adjust for your API
   {
      // Error! Handle it.
      break;
   }
   
   bytesSent += bytesWritten;
   
   if (bytesSent > inputSize)
   {
      // Something went horribly wrong
      break;
   }
}

Facile 😀.

(En réalité, vous devriez éventuellement utiliser un type non signé comme std::size_t, et non int, à moins que votre send renvoie une valeur négative en cas d'erreur.)

bytesToSend est la clé ici. Vous ne voudrez peut-être pas envoyer un morceau "complet" dans la dernière itération. C'est de là que viennent vos 16 Ko supplémentaires: votre entrée n'était pas un multiple exact de la taille du morceau.

0
Asteroids With Wings 9 déc. 2020 à 13:40
65217728