2010-06-21 12 views
5

In alcuni casi, vorrei scartare esplicitamente i pacchetti in attesa sul socket con il minor overhead possibile. Sembra che non ci sia una chiamata di sistema "drop udp buffer" esplicita, ma forse ho torto?Scarta pacchetto UDP in entrata senza leggere

Il prossimo modo migliore sarebbe probabilmente quello di recv il pacchetto in un buffer temporaneo e basta rilasciarlo. Sembra che non possa ricevere 0 byte, dal momento che l'uomo dice di recv: The return value will be 0 when the peer has performed an orderly shutdown. Quindi 1 è il minimo in questo caso.

C'è qualche altro modo per gestire questo?

Per ogni evenienza, questa non è un'ottica prematura. L'unica cosa che questo server sta facendo è di inoltrare/inviare i pacchetti UDP in un modo specifico - anche se recv con len=1 non mi ucciderà, preferirei semplicemente scartare l'intera coda in una volta sola con una funzione più specifica (si spera che abbassando il latenza).

+0

Quali criteri stai usando per decidere cosa scartare? –

+0

Non sono sicuro di quello che posso dire qui, quindi ha senso ... fondamentalmente due parti stanno annunciando (con un cookie condiviso) che hanno bisogno di un proxy. Il server deve aprire il socket dopo la prima richiesta per assicurarsi che la porta non sia utilizzata da nessun altro. Fino al completamento della configurazione, ho bisogno di rilasciare i pacchetti, altrimenti sono messi in coda e risentiti più tardi - è una cosa molto brutta nel mio scenario. Quindi in pratica ho una bandiera interna per ogni connessione che dice: rilascia tutto o inoltra tutto. – viraptor

risposta

8

Si può avere il kernel scartare i pacchetti UDP impostando l'UDP buffer di ricezione a 0.

int UdpBufSize = 0; 
socklen_t optlen = sizeof(UdpBufSize); 
setsockopt(socket, SOL_SOCKET, SO_RCVBUF, &UdpBufSize, optlen); 

Ogni volta che si vede in forma di ricevere i pacchetti, è possibile quindi impostare il buffer per, ad esempio, 4096 byte .

+1

È '& UdpBufSize', non è vero? ;) – viraptor

+0

Grazie per la cattura! :) – WindsurferOak

+0

C'è un modo per scartare selettivamente i pacchetti da uno specifico 'sockkaddr' w/o che deve' recv' entrare in un buffer temporaneo e quindi rilasciare il buffer? –

3

preferirei solo scartare l'intera coda in una sola volta

Dal momento che questo è UDP stiamo parlando qui: close(udp_server_socket) e socket()/bind() di nuovo?

Per la mia comprensione dovrebbe funzionare.

+0

Questa è una soluzione interessante ... sfortunatamente non funzionerà per un intervallo privilegiato dopo una radice dropping (se il socket è stato collegato prima). Ci proverò comunque. – viraptor

+0

Ah - e causerà errori nel client - che purtroppo non posso accettare ... – viraptor

+0

@viraptor: "causerà errori nel client" - solo se il client viene eseguito localmente. E i client dovrebbero ignorare gli errori da UDP in ogni caso (oltre a picchiare probabilmente un contatore di errori) in quanto il tipo di comunicazione non è comunque affidabile. Altrimenti, personalmente, non vedo alcun problema, sta semplicemente leggendo tutti i messaggi: il buffer di recv UDP di default è abbastanza piccolo e, anche se lo si esegue a pochi megabyte, è ancora disponibile per le moderne CPU. – Dummy00001

1

man dice di recv: il valore restituito sarà 0 quando il peer ha eseguito un arresto regolare.

Ciò non vale per UDP. Non c'è "connessione" per spegnere in UDP. Un valore restituito pari a 0 è perfettamente valido, significa solo datagramma senza payload ricevuto (vale a dire solo le intestazioni IP e UDP)

Non è sicuro che questo aiuti il ​​tuo problema o meno. Davvero non capisco dove stai andando con la roba len = 1.

+0

Non completamente vero. È possibile chiamare connect su un socket UDP che causerà il rifiuto dei pacchetti da qualsiasi altro host: porta combo e consentirà il recapito degli errori di rete ICMP al socket. –

+0

Connessione! = Connessione però. Non c'è una stretta di mano, nessuna lacrima, nessun ordine di pacchetti o qualcosa che la maggior parte delle persone comunemente associa a una connessione. A mio parere, connettersi è un termine improprio con UDP e porta alla confusione. – Duck

+0

Non sono d'accordo e dico che è tanto una connessione quanto 'TCP'. Ricorda che anche in "TCP" ogni estremità mantiene il proprio stato indipendente e se un capo si arresta in modo anomalo, l'altro non lo saprà mai fino a quando non eseguono due mandate e ottengono un errore di pipe non funzionante. Il concetto di "connessione" nella mia mente si riferisce al fatto che tu stia parlando in modo molto diretto o uno a uno in modo forzato. Naturalmente ci sono argomenti per vederlo in entrambi i modi :-) –

Problemi correlati