Genau wie die Handbuchseite sagt, sind Unix-Sockets immer zuverlässig. Der Unterschied zwischen SOCK_STREAM
und SOCK_DGRAM
liegt in der Semantik des Konsumierens von Daten aus dem Socket.
Der Stream-Socket ermöglicht das Lesen einer beliebigen Anzahl von Bytes, behält jedoch die Byte-Reihenfolge bei. Mit anderen Worten, ein Sender könnte 4 KB Daten in den Socket schreiben, und der Empfänger kann diese Daten Byte für Byte verbrauchen. Umgekehrt gilt das auch - der Absender kann mehrere kleine Nachrichten an den Socket schreiben, die der Empfänger in einem Lesevorgang verbrauchen kann. Stream-Socket behält Nachrichtengrenzen nicht bei.
Der Datagramm-Socket hingegen behält diese Grenzen bei - ein Schreibvorgang durch den Sender entspricht immer einem Lesevorgang durch den Empfänger (selbst wenn der Puffer des Empfängers an read(2)
übergeben wurde oder recv(2)
ist kleiner als diese Nachricht).
Wenn Ihr Anwendungsprotokoll also kleine Nachrichten mit bekannter Obergrenze für die Nachrichtengröße enthält, sind Sie mit SOCK_DGRAM
besser dran da dies einfacher zu verwalten ist.
Wenn Ihr Protokoll willkürlich lange Nachrichtennutzlasten erfordert oder nur ein unstrukturierter Stream ist (wie rohes Audio oder so), wählen Sie SOCK_STREAM
und führen Sie die erforderliche Pufferung durch.
Die Leistung sollte gleich sein, da beide Typen nur den lokalen In-Kernel-Speicher durchlaufen, nur die Pufferverwaltung ist unterschiedlich.
-
Ein wahrscheinlicher Unterschied sind Nachrichtengrenzen. Datagramme werden als Ganzes geliefert, wobei die Datagramme die natürlichen Nachrichtengrenzen sind. Mit Stream-Sockets können Sie N Bytes lesen und der Socket blockiert, bis N Bytes bereit sind. Dies bedeutet jedoch keine offensichtlichen Nachrichtengrenzen.
-
Unter sonst gleichen Bedingungen ist Geschwindigkeit ein Anliegen, Instrument und Maßstab. (Ich nehme an, Sie wissen bereits, dass nur ein Stream-Socket einen integrierten zuverlässigen Transport in der Reihenfolge bietet und nur Datagramm-Sockets zum Senden an mehrere verwendet werden können Empfänger).
Der Hauptunterschied besteht darin, dass eines verbindungsbasiert ist (STREAM
) und der andere ist verbindungslos (DGRAM
) - der Unterschied zwischen stream- und paketorientierter Kommunikation ist normalerweise viel weniger wichtig.
Mit SOCK_STREAM
Sie erhalten immer noch die gesamte Verbindungsbehandlung, dh listen
/accept
und Sie können feststellen, ob eine Verbindung von der anderen Seite geschlossen wird.
Beachten Sie, dass es auch einen SEQPACKET
gibt Socket-Typ, der immer noch verbindungsorientiert ist, aber Nachrichtengrenzen beibehält (was Sie möglicherweise davon abhält, eine nachrichtenorientierte Ebene auf einem STREAM
zu implementieren Steckdose).
Ich würde erwarten, dass die Datenübertragungsleistung für alle diese Typen ähnlich ist, der Hauptunterschied besteht nur darin, welche Semantik Sie wollen.