2010-01-24 11 views
20

Se utilizzo i socket UDP per la comunicazione tra processi, posso aspettarmi che tutti i dati di invio vengano ricevuti dall'altro processo nello stesso ordine?L'invio di dati tramite socket UDP sulla stessa macchina è affidabile?

So che questo non è vero per UDP in generale.

+0

Non c'è controllo di flusso. Il superamento di una quota del buffer del kernel non è improbabile. Utilizzare invece pipe con nome. –

+6

Su UNIX, i socket di datagrammi del dominio UNIX locale ('socket (AF_UNIX, SOCK_DGRAM, 0)') sono garantiti come affidabili, con la stessa identica API di UDP. Purtroppo, Windows non ha socket di dominio UNIX; se ti adatti all'utilizzo dell'API Win32 invece di Winsock, puoi usare 'CreateNamedPipe' ecc. – ephemient

risposta

30

No. Sono stato morso da questo prima. Potresti chiederti come possa fallire, ma ti imbatterai in problemi di buffer dei pacchetti in sospeso che si riempiono, e di conseguenza i pacchetti verranno eliminati. Il modo in cui il sottosistema di rete elimina i pacchetti dipende dall'implementazione e non viene specificato in alcun luogo.

+1

L'impostazione di un ampio buffer di ricezione con setsockopt aiuta ma probabilmente non garantisce nulla. Certamente i miei test dimostrano che ha un effetto diretto sulla perdita di pacchetti su Windows 7. Ma senza controllo del flusso si sta solo ritardando l'inevitabile. –

+0

@LenHolgate Ritardare l'inevitabile se il ciclo del processo è lento, che in tal caso potrebbe verificarsi l'inevitabile flusso continuo di dati anche per connessioni affidabili, ora sul sito del mittente. – dashesy

7

In breve, no. Non si dovrebbero formulare ipotesi sull'ordine dei dati ricevuti su un socket UDP, anche su localhost. Potrebbe funzionare, potrebbe non esserlo e non è garantito.

1

L'interfaccia socket probabilmente non controllerà il flusso dell'originatore dei dati, quindi sarà probabilmente possibile vedere una trasmissione affidabile se si dispone di un controllo del flusso di livello superiore ma c'è sempre la possibilità che un crunch della memoria possa ancora causare un datagramma interrotto.

Senza il controllo del flusso che limita l'allocazione della memoria del kernel per i datagrammi, immagino che sarà altrettanto inaffidabile quanto l'UDP di rete.

5

No, non esiste tale garanzia, anche con prese locali. Se si desidera un meccanismo IPC che garantisca la consegna in ordine, è possibile utilizzare le pipe full duplex con popen(). Ciò apre una pipe al processo figlio che può leggere o scrivere arbitrariamente. Garantirà la consegna in ordine e può essere utilizzato con I/O sincrono o asincrono (select() o poll()), a seconda di come si desidera creare l'applicazione.

Su unix ci sono altre opzioni come socket di dominio unix o code di messaggi System V (alcune delle quali potrebbero essere più veloci) ma leggere/scrivere da una pipe è semplice e funziona. Come bonus è facile testare il processo del server perché è solo la lettura e la scrittura da Stdio.

Su Windows è possibile esaminare Named Pipes, che funzionano in modo un po 'diverso dal loro omonimo unix, ma sono utilizzati proprio per questo tipo di comunicazione tra processi.

2

Loopback UDP è incredibilmente inaffidabile su molte piattaforme, è possibile vedere facilmente il 50% di perdita di dati. Varie scuse sono state date al fatto che ci sono meccanismi di trasporto molto migliori da usare.

Attualmente ci sono molti stack di middleware disponibili per rendere l'IPC più facile da usare e multipiattaforma. Dai un'occhiata a qualcosa come ZeroMQ o 29 West's LBM che usa la stessa API per le comunicazioni intra-process, inter-process (IPC) e di rete.