Proprio come dice la pagina di manuale, i socket Unix sono sempre affidabili. La differenza tra SOCK_STREAM
e SOCK_DGRAM
è nella semantica del consumo di dati dal socket.
Lo stream socket consente di leggere un numero arbitrario di byte, preservando comunque la sequenza di byte. In altre parole, un mittente potrebbe scrivere 4K di dati nel socket e il destinatario può consumare quei dati byte per byte. È vero anche il contrario:il mittente può scrivere diversi piccoli messaggi sul socket che il destinatario può consumare in una sola lettura. Lo stream socket non preserva i limiti dei messaggi.
Il socket del datagramma, d'altra parte, preserva questi limiti:una scrittura da parte del mittente corrisponde sempre a una lettura da parte del destinatario (anche se il buffer del destinatario è assegnato a read(2)
o recv(2)
è più piccolo di quel messaggio).
Quindi, se il tuo protocollo applicativo ha messaggi piccoli con limite superiore noto sulla dimensione del messaggio, stai meglio con SOCK_DGRAM
poiché è più facile da gestire.
Se il tuo protocollo richiede payload di messaggi lunghi arbitrari o è solo un flusso non strutturato (come audio non elaborato o qualcosa del genere), scegli SOCK_STREAM
ed eseguire il buffering richiesto.
Le prestazioni dovrebbero essere le stesse poiché entrambi i tipi passano solo attraverso la memoria interna del kernel, solo la gestione del buffer è diversa.
-
Una probabile differenza sono i limiti del messaggio. I datagrammi verranno consegnati nel loro insieme con i datagrammi che rappresentano i limiti naturali del messaggio. Con i socket stream puoi leggere N byte e il socket si bloccherà finché N byte non saranno pronti. Ma questo significa che non ci sono limiti di messaggio evidenti.
-
A parità di condizioni, se la velocità è una preoccupazione, strumento e misura. (Presumo che tu sappia già che solo un socket di flusso fornisce un trasporto in ordine affidabile integrato e che solo i socket di datagramma possono essere utilizzati per inviare a più ricevitori).
La differenza principale è che uno è basato sulla connessione (STREAM
) e l'altro è senza connessione (DGRAM
) - la differenza tra la comunicazione orientata al flusso e quella orientata ai pacchetti è di solito molto meno importante.
Con SOCK_STREAM
ottieni ancora tutta la gestione della connessione, ad esempio listen
/accept
e puoi sapere se una connessione è chiusa dall'altra parte.
Nota che c'è anche un SEQPACKET
tipo di socket che è ancora orientato alla connessione, ma preserva i limiti dei messaggi (il che potrebbe salvarti dall'implementare un livello orientato ai messaggi sopra un STREAM
presa).
Mi aspetto che le prestazioni di trasferimento dei dati siano simili per tutti questi tipi, la differenza principale è proprio la semantica che desideri.