Tout comme le dit la page de manuel, les sockets Unix sont toujours fiables. La différence entre SOCK_STREAM
et SOCK_DGRAM
est dans la sémantique de la consommation de données hors du socket.
La socket de flux permet de lire un nombre arbitraire d'octets, tout en préservant la séquence d'octets. En d'autres termes, un expéditeur peut écrire 4 Ko de données sur le socket et le destinataire peut consommer ces données octet par octet. L'inverse est également vrai - l'expéditeur peut écrire plusieurs petits messages sur le socket que le destinataire peut consommer en une seule lecture. Le socket de flux ne conserve pas les limites des messages.
Le socket de datagramme, en revanche, préserve ces limites - une écriture par l'expéditeur correspond toujours à une lecture par le destinataire (même si le tampon du destinataire est read(2)
ou recv(2)
est plus petit que ce message).
Donc, si votre protocole d'application a de petits messages avec une limite supérieure connue sur la taille du message, vous êtes mieux avec SOCK_DGRAM
car c'est plus facile à gérer.
Si votre protocole appelle des charges utiles de messages longs arbitraires, ou s'il s'agit simplement d'un flux non structuré (comme de l'audio brut ou autre), alors choisissez SOCK_STREAM
et effectuez la mise en mémoire tampon requise.
Les performances doivent être les mêmes puisque les deux types passent simplement par la mémoire locale du noyau, seule la gestion des tampons est différente.
-
Une différence probable réside dans les limites des messages. Les datagrammes seront livrés dans leur ensemble, les datagrammes étant les limites naturelles du message. Avec les sockets de flux, vous pouvez lire N octets et la socket se bloquera jusqu'à ce que N octets soient prêts. Mais cela signifie qu'il n'y a pas de limites de message évidentes.
-
Toutes choses égales par ailleurs, si la vitesse est une préoccupation, un instrument et une mesure. (Je suppose que vous savez déjà que seule une socket de flux fournit un transport intégré fiable dans l'ordre, et que seules les sockets de datagramme peuvent être utilisées pour envoyer à plusieurs récepteurs).
La principale différence est que l'un est basé sur la connexion (STREAM
) et l'autre est sans connexion (DGRAM
) - la différence entre les communications orientées flux et paquets est généralement beaucoup moins importante.
Avec SOCK_STREAM
vous obtenez toujours toute la gestion de la connexion, c'est-à-dire listen
/accept
et vous pouvez savoir si une connexion est fermée par l'autre côté.
Notez qu'il y a aussi un SEQPACKET
type de socket qui est toujours orienté connexion, mais préserve les limites des messages (ce qui peut vous éviter d'implémenter une couche orientée message au-dessus d'un STREAM
prise).
Je m'attendrais à ce que les performances de transfert de données soient similaires pour tous ces types, la principale différence étant simplement la sémantique que vous souhaitez.