Il semble y avoir au moins 3 types de socket local/unix différents (PF_UNIX), SOCK_STREAM, SOCK_DGRAM et SOCK_SEQPACKET.
Bien que je sache qu'un SOCK_STREAM vous donne un flux d'octets bidirectionnel, comme TCP ou un tuyau bidirectionnel, et que les deux autres vous donnent une API messge/packet, quelle est la différence entre un socket unix de SOCK_DGRAM et SOCK_SEQPACKET?
Celles-ci étant uniquement locales, je ne vois pas pourquoi on implémenterait SOCK_DGRAM de manière à pouvoir réorganiser les paquets.
De plus, SOCK_DGRAM/SOCK_SEQPACKET utilise-t-il le contrôle de flux ou les messages peuvent-ils être supprimés en cas de lecture lente?
Voici un bon article sur le cas d'utilisation prévu de SOCK_SEQPACKET
, le fait qu'il ne soit pas vraiment disponible dans les familles de protocoles IP et comment obtenir la même chose avec la sémantique TCP existante:
http://Urchin.earth.li/~twic/Sequenced_Packets_Over_Ordinary_TCP.html
Notez que SOCK_SEQPACKET
a un comportement beaucoup plus proche de SOCK_STREAM
que de SOCK_DGRAM
.
Citant sur le site référencé:
Le type de socket SOCK_SEQPACKET est similaire au type SOCK_STREAM et est également orienté connexion. La seule différence entre ceux-ci types est que les limites d’enregistrement sont conservées à l’aide du Type SOCK_SEQPACKET. Un enregistrement peut être envoyé en utilisant une ou plusieurs sorties opérations et reçues en utilisant une ou plusieurs opérations d'entrée, mais un une seule opération ne transfère jamais des parties de plus d'un enregistrement. Record les limites sont visibles pour le destinataire via l'indicateur MSG_EOR dans le fichier reçu les indicateurs de message renvoyés par la fonction recvmsg (). Il est spécifique au protocole si une taille d'enregistrement maximale est imposée.
SOCK_SEQPACKET vous donne les garanties de SOCK_STREAM (conservation de la commande, livraison garantie, pas de duplication), mais avec des limites de paquets délimitées, comme SOCK_DGRAM. Donc, fondamentalement, c'est une combinaison des deux types de protocoles.
Dans la famille TCP/IP, SCTP implémente à la fois SOCK_STREAM (type TCP) et SOCK_SEQPACKET. Malheureusement, il n'est pas disponible en stock sous Windows.
socket (2) page de manuel fournie par Linux: “DGRAM: datagrammes (sans connexion, messages non fiables), SEQPACKET: chemin de transmission de données basé sur une connexion séquencée, fiable, [bidirectionnel] pour les datagrammes". Différence significative.
unix (7) page de manuel fournie par Linux indique: “SOCK_DGRAM, pour un socket orienté datagramme qui préserve les limites des messages [mais pas nécessairement dans l'ordre] [...] SOCK_SEQPACKET, pour un orienté connexion socket qui préserve les limites des messages et distribue les messages dans l'ordre dans lequel ils ont été envoyés. ”
La norme permet de recevoir les paquets réorganisés avec SOCK_DGRAM. (En d'autres termes, si un système d'exploitation vous les remet dans l'ordre, il s'agit d'une fonctionnalité spécifique à la mise en œuvre. Ou simplement du hasard.)
Il existe un contrôle de flux dans l'implémentation af_file/af_unix sous Linux, mais cela n'a pas besoin d'être corrélé avec le comportement standard spécifié.
Tout comme TCP et les sockets UDP, il existe des sockets SCTP (protocole de transmission de contrôle de flux) ayant deux formes (une à une) et (une à plusieurs) entre les points finaux. Un à un utilise SOCK_STREAM et un à plusieurs utilise SOCK_SEQPACKET
Je pense que la principale différence ici est que SOCK_SEQPACKET
est conneciton-orienté, alors que SOCK_DGRAM
ne l’est pas.
Cela importera surtout du côté serveur de la connexion (le processus qui écoute sur le socket UNIX) lorsqu'il y a plusieurs processus clients qui lui parlent:
Avec SOCK_DGRAM
, vous obtiendrez des datagrammes clients entrelacés directement sur le socket d’écoute. Avec SOCK_SEQPACKET
, vous créeriez une socket client distincte pour chaque client utilisant accept
, recevant ainsi des datagrammes de chaque client séparément.
Citer man 3 accept
:
L'appel système accept () est utilisé avec les types de socket basés sur la connexion (SOCK_STREAM, SOCK_SEQPACKET).