100 votes

Qu'est-ce que SOCK_DGRAM et SOCK_STREAM?

Je viens de tomber sur cette chose étrange que j'ai eu l'application à voir est qu'ils utilisent par défaut la fonction SOCK_STREAM. Pourquoi est-ce ainsi? Est-ce que SOCK_STREAM crée simplement plusieurs flux? Ou est-ce la fonction standard SOCK_STREAM disponible pour créer un/des flux TCP?

Je pensais que le tsunami était basé sur UDP, mais possédait toujours certaines fonctionnalités similaires à celles du TCP, par exemple l'équité TCP, la convivialité, etc.

Est-ce que quelqu'un pourrait éclaircir cette question? Je suis totalement confus à ce sujet.

121voto

Michael J Points 4112

TCP utilise presque toujours SOCK_STREAM et UDP utilise SOCK_DGRAM.

TCP (SOCK_STREAM) est un protocole basé sur la connexion. La connexion est établie et les deux parties ont une conversation jusqu'à ce que la connexion soit terminée par l'une des parties ou par une erreur réseau.

UDP (SOCK_DGRAM) est un protocole basé sur le datagramme. Vous envoyez un datagramme et obtenez une réponse, puis la connexion se termine.

  • Si vous envoyez plusieurs paquets, TCP promet de les livrer dans l'ordre. UDP ne le fait pas, donc le destinataire doit les vérifier si l'ordre est important.

  • Si un paquet TCP est perdu, l'émetteur peut le savoir. Ce n'est pas le cas pour UDP.

  • Les datagrammes UDP sont limités en taille, de mémoire je pense que c'est 512 octets. TCP peut envoyer des morceaux beaucoup plus gros que cela.

  • TCP est un peu plus robuste et effectue plus de vérifications. UDP est un peu plus léger (moins de contraintes sur l'ordinateur et le réseau).

Choisissez le protocole approprié en fonction de la manière dont vous souhaitez interagir avec l'autre ordinateur.

83voto

Ian Boyd Points 50743

Une des idées derrière le Berkley Sockets API était qu'il pouvait utiliser différentes familles de protocoles - pas seulement le Protocole Internet (IP). Mais au lieu de cela, vous aviez une API qui pouvait gérer toutes sortes d'"familles d'adresses", par exemple :

  • Version 4 du Protocole Internet (IPv4) : AF_INET
  • IPX/SPX : AF_IPX
  • AppleTalk : AF_APPLETALK
  • NetBIOS : AF_NETBIOS
  • Version 6 du Protocole Internet (IPv6) : AF_INET6
  • Association de Données Infrarouge (IrDA) : AF_IRDA
  • Bluetooth : AF_BTH

Chaque famille de protocoles a généralement quelques concepts similaires sur la manière dont les données seront traitées sur un socket :

  • séquencé, fiable, bidirectionnel, basé sur la connexion, flux d'octets : SOCK_STREAM (ce qu'une personne IP appellerait TCP)
  • non connecté, non fiable, datagrammes : SOCK_DGRAM (ce qu'une personne IP appellerait UDP)

Les différentes familles d'adresses ont différents termes pour ces concepts de base :

╔═══════════╦══════════════════════════╗
║           ║       Type de Socket      ║
║ Adresse   ╟────────────┬─────────────╢
║ Familia   ║ SOCK_DGRAM │ SOCK_STREAM ║ 
╠═══════════╬════════════╪═════════════╣
║ IPX/SPX   ║ SPX        │ IPX         ║
║ NetBIOS   ║ NetBIOS    │ n/a         ║
║ IPv4      ║ UDP        │ TCP         ║
║ AppleTalk ║ DDP        │ ADSP        ║
║ IPv6      ║ UDP        │ TCP         ║
║ IrDA      ║ IrLMP      │ IrTTP       ║
║ Bluetooth ║ ?          │ RFCOMM      ║
╚═══════════╩════════════╧═════════════╝

Le point est :

  • Si vous voulez des flux d'octets séquencés, fiables, bidirectionnels et basés sur la connexion
  • vous en faites la demande en utilisant "SOCK_STREAM"
  • et l'API des sockets se chargera de comprendre que vous voulez TCP

De même, si je créais un socket sur Infrarouge (IrDA, AF_IRDA) :

  • je n'ai aucune idée du protocole dans IrDA qui soit fiable, séquencé et basé sur la connexion
  • tout ce que je sais, c'est que je veux quelque chose qui soit fiable, séquencé et basé sur la connexion

Donc vous dites :

socket(AF_IRDA, SOCK_STREAM, 0);

Et les Sockets le comprendront pour moi.

En Plus

À l'origine, il n'y avait que deux options de protocole :

  • datagrammes non connectés, non fiables (SOCK_DGRAM)
  • basé sur la connexion, fiable, séquencé, bidirectionnel (SOCK_STREAM)

Plus tard, d'autres choix de protocole ont été ajoutés :

  • un datagramme de message fiable (SOCK_RDM - "Reliable Datagram Multicast" - obsolète ; ne pas utiliser dans de nouveaux programmes)
  • paquets séquencés pseudo-flux basés sur les datagrammes (SOCK_SEQPACKET)

    ╔═══════════╦══════════════════════════════════════════════════════╗ ║ ║ Type de Socket ║ ║ Adresse ╟────────────┬─────────────┬──────────┬────────────────╢ ║ Familia ║ SOCK_DGRAM │ SOCK_STREAM │ SOCK_RDM │ SOCK_SEQPACKET ║ ╠═══════════╬════════════╪═════════════╪══════════╪══════════════

8voto

Code Painters Points 3646

Mise à jour: ma réponse semble être plus pertinente, mais la question originale faisait référence à UDT, qui est un protocole orienté connexion construit sur UDP. Plus d'infos ici: http://en.wikipedia.org/wiki/UDP-based_Data_Transfer_Protocol


UDT semble fournir une API qui imite l'API classique des sockets BSD, donc elle peut être utilisée comme un remplacement direct, à la fois pour les applications orientées flux et datagramme. Vérifiez par exemple sendmsg et recvmsg - ils lancent tous les deux une exception s'ils sont utilisés sur un socket créé avec SOCK_STREAM, et toutes les API orientées flux lancent une exception pour un socket créé avec SOCK_DGRAM également.

Dans le cas de SOCK_DGRAM, il effectue cependant un traitement supplémentaire, il ne se contente pas d'envelopper le socket UDP de manière transparente dans ce cas - du moins d'après ce que je comprends du code après un examen rapide (je ne connais pas l'intérieur d'UDT ou la spécification du protocole). Lire les documents techniques pourrait beaucoup aider.

La bibliothèque crée toujours son socket sous-jacent, "réel", comme un socket datagramme (vérifiez channel.cpp, CChannel::open).

-6voto

TCP utilise SOCK_STREAM et UDP utilise SOCK_DGRAM.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X