2009-07-08 6 views
12

Sto lavorando alla scrittura di un'applicazione di rete in C++ sulla piattaforma Linux utilizzando l'API tipica dei socket e sto osservando 2 modi alternativi di scrittura un array di byte in un flusso TCP: chiamando write() o chiamando send(). So che, poiché questo è Linux, l'handle del socket è semplicemente un descrittore di file, e quindi è valido per eseguire chiamate read() e write() sul socket, tuttavia l'API socket fornisce anche send() e recv () funzioni per eseguire le stesse attività.Impatto delle prestazioni dell'uso di write() invece di send() durante la scrittura su un socket

Mi chiedo quindi se esista una ragione particolare per scegliere una classe di funzioni rispetto all'altra: le funzioni di invio/ricezione ottimizzate per la scrittura/lettura di rete, hanno prestazioni migliori, ecc.? O è davvero arbitrario quali funzioni uso? Read() e write() si comportano correttamente in tutti i casi?

Grazie per eventuali approfondimenti!

risposta

19

Non ci dovrebbero essere differenze. Citando man 2 send:

L'unica differenza tra send() e write() è la presenza di bandiere. Con il parametro zero flags, send() equivale a write().

Finché non si vuole specificare e bandiere per send() è possibile utilizzare write() liberamente.

+0

È vero anche per FreeBSD o altre piattaforme? - quella linea non appare nella mia manpage send (2). –

+0

@GoodPerson Si applica a tutte le piattaforme. Se così non fosse, 'inetd' e simili non funzionerebbero. ('inetd' dups il tuo socket nello stdin e stdout del processo daemon, e il tuo processo può interagire direttamente con stdin e stdout nel modo normale, senza alcuna consapevolezza che siano socket. Naturalmente, puoi anche fare il socket con loro. –

6

recv e send consentono di specificare contrassegni, ad esempio per pacchetti fuori banda. Se non è necessario specificare i flag, read e write sono perfettamente adeguati.

1

write v.s. send per un singolo byte, o un singolo array probabilmente non sarà molto diverso - presto finiranno lo stesso percorso di codice (in definitiva eseguiranno la stessa operazione). Il sovraccarico nella trasmissione di rete è altamente improbabile che si verifichi a tale livello; sarà la connessione TCP effettiva e lo spostamento dei bit su fili.

Tuttavia, se si intende inviare messaggi di grandi dimensioni in più parti in un'unica operazione, è necessario esaminare il syscall sendmsg() - questo consente di specificare un elenco di matrici non contigue di dati da inviare.

Alla fine della giornata si applicano le normali linee guida: scrivere prima l'applicazione, quindi il benchmark per vedere dove sono i colli di bottiglia.

+1

Su array non contigui da ricevere/inviare: readv e writev lo consentono anche. Yay per scatter/gather I/O! –

Problemi correlati