Est-il préférable d’envoyer 1 gros morceau ou beaucoup de petits quand on utilise TCP?

Après avoir accept() une connexion, puis write() sur le socket client, est-il préférable d’écrire toutes les données que vous souhaitez envoyer en une fois ou de les envoyer en morceaux?

Par exemple:

accepter, écrire 1 Mo, déconnecter

…ou…

accepter, écrire 256 octets, écrire 256 octets,… n, déconnecter

Mon instinct me dit que le protocole sous-jacent le fait automatiquement, avec correction des erreurs, etc. Est-ce correct, ou devrais-je fragmenter mes données?

Avant que vous ne posiez la question, non, je ne suis pas sûr d’où j’ai eu l’idée de regrouper les données – je pense que c’est un instinct que j’ai appris à programmer des services Web C # (pour contourner les limites de mémoire tampon, etc., je pense). Mauvaise habitude?

Note : J’utilise C

Le client et le serveur séparent vos données à votre guise, afin que vous puissiez envoyer autant que vous le souhaitez en un seul bloc. Consultez l’article de Windows sur Von Welch du Guide de l’utilisateur au protocole TCP .

Il y a des années et des années, j’avais une application qui envoyait des données binarys – elle en envoyait une avec la taille du tampon suivant, puis une autre avec le tampon (quelques centaines d’octets). Et après le profilage, nous avons découvert que nous pouvions obtenir une accélération importante en les transformant en un seul tampon et en les envoyant une seule fois. Nous avons été surpris – même s’il y a des frais généraux de réseau sur chaque paquet, nous ne pensions pas que cela allait être un facteur notable.

L’ algorithme Nagle , qui est généralement activé par défaut sur les sockets TCP, combinera probablement ces quatre écritures de 256 octets dans le même paquet. Donc, peu importe si vous l’envoyez en une ou plusieurs fois, il devrait quand même se retrouver dans un paquet. L’envoyer comme un seul bloc a plus de sens si vous avez un gros morceau pour commencer.

A partir d’un niveau TCP, oui, votre grand tampon sera scindé lorsqu’il est trop grand et il sera combiné s’il est trop petit.

Au niveau de l’application, ne laissez pas votre application gérer des tailles de tampon non limitées . À un certain niveau, vous devez les séparer.

Si vous envoyez un fichier sur un socket, et peut-être que vous traitez certaines des données de ce fichier, par exemple en le compressant. Ensuite, vous devez diviser cela en morceaux. Sinon, vous utiliserez trop de RAM lorsque vous rencontrerez un fichier volumineux et que votre programme sera à court de RAM.

La RAM n’est pas le seul problème. Si votre mémoire tampon devient trop volumineuse, vous passerez peut-être trop de temps à lire ou à traiter les données et à ne pas utiliser le socket qui attend en attente des données. Pour cette raison, il est préférable d’avoir un paramètre pour la taille de la mémoire tampon afin de pouvoir déterminer une valeur qui n’est ni trop petite ni trop grande.

Mon affirmation n’est pas qu’un socket TCP ne puisse pas gérer une grande quantité de données, il le peut et je suggère d’utiliser des mémoires tampons plus grandes lors de l’envoi pour obtenir une meilleure efficacité. Ma demande est simplement de ne pas traiter les tailles de tampon non liées dans votre application.

Si vous calculez les données entre ces écritures, il peut être préférable de les diffuser en continu, car elles sont disponibles. De plus, les écrire tous en même temps peut produire des dépassements de mémoire tampon (bien que ce soit probablement rare, cela arrive), ce qui signifie que votre application doit mettre en pause et réessayer les écritures (pas toutes, juste à partir du point où vous avez dépassé le seuil de débordement. .)

En général, je ne me mettrais pas en quatre pour rédiger les écritures, surtout si elles n’étaient pas aussi petites que des fragments de 256 octets. (Puisqu’environ 1500 octets peuvent tenir dans un paquet Ethernet après le temps système TCP / IP, j’utiliserais des morceaux au moins aussi gros.)

Je voudrais envoyer tous dans un gros morceau comme les couches sous-jacentes dans le modèle osi . Par conséquent, vous n’avez pas à vous soucier de la quantité de morceaux que vous envoyez, car les couches seront divisées en necisarry.

La seule réponse absolue est de profiler l’application au cas où. Il y a tellement de facteurs qu’il est impossible de donner une réponse exacte, qui est correcte dans tous les cas.