2010-06-21 6 views
5

In einigen Fällen möchte ich Pakete, die auf den Socket warten, mit möglichst wenig Overhead explizit verwerfen. Es scheint, dass es keinen expliziten "Drop Udp Buffer" Systemaufruf gibt, aber vielleicht liege ich falsch?Einfallendes UDP-Paket ohne Lesen löschen

Der nächste beste Weg wäre wahrscheinlich zu recv das Paket in einen temporären Puffer und einfach fallen lassen. Es scheint, ich kann 0 Bytes nicht empfangen, da man sagt über recv: The return value will be 0 when the peer has performed an orderly shutdown. Also 1 ist das Minimum in diesem Fall.

Gibt es einen anderen Weg, damit umzugehen?

Nur für den Fall - das ist keine vorzeitige Optimierung. Das einzige, was dieser Server macht, ist das Weiterleiten/Versenden der UDP-Pakete in einer bestimmten Weise - obwohl recv mit len=1 mich nicht umbringt, würde ich lieber die ganze Warteschlange auf einmal mit einer spezifischeren Funktion verwerfen (hoffentlich die Latenz).

+0

Welche Kriterien verwenden Sie, um zu entscheiden, was zu verwerfen ist? –

+0

Nicht sicher, was ich hier sagen kann, also macht es Sinn ... im Grunde kündigen zwei Seiten (mit einem geteilten Cookie) an, dass sie einen Proxy benötigen. Der Server muss den Socket nach der ersten Anfrage öffnen, um sicherzustellen, dass der Port von niemandem benutzt wird. Bis das Setup abgeschlossen ist, muss ich Pakete löschen, sonst werden sie in die Warteschlange gestellt und später erneut gesendet - das ist eine sehr schlechte Sache in meinem Szenario. Also im Grunde habe ich eine interne Flagge für jede Verbindung, die sagt - alles fallen lassen oder alles weiterleiten. – viraptor

Antwort

8

Sie haben kann der Kernel Ihre UDP-Pakete verwerfen durch die UDP-Puffer auf 0.

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

erhalten Einstellung Jedes Mal, wenn Sie sehen, passen Pakete zu empfangen, können Sie einstellen, dann den Puffer, beispielsweise 4096 Bytes .

+1

Es ist '& UdpBufSize', oder? ;) – viraptor

+0

Danke für den Fang! :) – WindsurferOak

+0

Gibt es eine Möglichkeit, Pakete selektiv von einem bestimmten "Sockkaddr" zu verwerfen, ohne in einen temporären Puffer "recv" zu müssen und dann den Puffer fallen zu lassen? –

3

Ich würde lieber nur die ganze Warteschlange verwerfen in einer

Da dies gehen wird UDP wir sprechen hier: close(udp_server_socket) und socket()/bind() wieder?

Zu meinem Verständnis sollte funktionieren.

+0

Das ist eine interessante Lösung ... leider funktioniert das nicht für den privilegierten Bereich nach einer abfallenden Wurzel (wenn der Socket zuvor gebunden war). Ich werde es versuchen. – viraptor

+0

Ah - und es werden Fehler an den Client zurückgegeben - die ich leider nicht akzeptieren kann ... – viraptor

+0

@viraptor: "es wird dazu führen, dass Fehler an den Client zurückgegeben werden" - nur wenn der Client lokal ausgeführt wird. Und Clients sollten sowieso Fehler von UDP ignorieren (abgesehen davon, dass sie wahrscheinlich einen Fehlerzähler stoßen), da der Kommunikationstyp sowieso nicht zuverlässig ist. Sonst sehe ich persönlich kein Problem darin, einfach alle Nachrichten auszulesen: UDP Recv Buffer ist standardmäßig klein genug und selbst wenn man es auf wenige Megs stößt, ist es für moderne CPUs immer noch ein Kinderspiel. – Dummy00001

1

man sagt über recv: der Rückgabewert wird 0 sein, wenn der Peer eine ordnungsgemäße Abschaltung durchgeführt hat.

Das gilt nicht für UDP. Es gibt keine "Verbindung" zum Herunterfahren in UDP. Ein Rückgabewert von 0 ist absolut gültig, es bedeutet nur Datagramm ohne Nutzdaten (d. H. Nur die IP- und UDP-Header).

Nicht sicher, ob das Ihrem Problem hilft oder nicht. Ich verstehe wirklich nicht, wohin du mit den len = 1 Sachen gehst.

+0

Nicht ganz richtig. Sie können connect auf einem UDP-Socket aufrufen, was dazu führt, dass Pakete von anderen Hosts abgelehnt werden: port combo und ermöglicht die Zustellung von ICMP-Netzwerkfehlern an den Socket. –

+0

Connect! = Verbindung obwohl. Es gibt keinen Handschlag, keinen Abbruch, keine Bestellung von Paketen oder irgendetwas, was die meisten Leute mit einer Verbindung verbinden. Connection ist meiner Meinung nach eine falsche Bezeichnung mit UDP und führt zu Verwirrung. – Duck

+0

Ich würde nicht zustimmen und sagen, dass es genauso eine Verbindung wie 'TCP' ist. Denken Sie daran, dass sogar in 'TCP' jedes Ende seinen eigenen unabhängigen Zustand beibehält, und wenn ein Ende abstürzt, wird der andere nie darüber Bescheid wissen, bis sie zwei Sends ausführen und einen gebrochenen Rohrfehler erhalten. Das Konzept der "Verbindung" in meinem Kopf bezieht sich auf die Frage, ob Sie in einer Art und Weise, die erzwungen wird, von einer Eins-zu-Eins-Beziehung sprechen. Natürlich gibt es Argumente, um es so oder so zu sehen :-) –

Verwandte Themen