2010-06-21 17 views
5

En algunos casos, me gustaría descartar explícitamente los paquetes que esperan en el socket con la menor sobrecarga posible. Parece que no hay una llamada explícita del sistema "drop udp buffer", pero ¿tal vez estoy equivocado?Desechar el paquete UDP entrante sin leer

La siguiente mejor manera sería probablemente recv el paquete en un búfer temporal y simplemente soltarlo. Parece que no puedo recibir 0 bytes, ya que el hombre dice sobre recv: The return value will be 0 when the peer has performed an orderly shutdown. Entonces 1 es el mínimo en este caso.

¿Hay alguna otra forma de manejar esto?

Por las dudas, esta no es una optimización prematura. Lo único que hace este servidor es reenviar/despachar los paquetes UDP de una manera específica, aunque recv con len=1 no me va a matar, prefiero descartar toda la cola de una sola vez con alguna función más específica (con suerte, bajando el estado latente).

+0

¿Qué criterios está utilizando para decidir qué descartar? –

+0

No estoy seguro de lo que puedo decir aquí, así que tiene sentido ... básicamente dos lados están anunciando (con alguna cookie compartida) que necesitan un proxy. El servidor debe abrir el socket después de la primera solicitud para asegurarse de que nadie más use el puerto. Hasta que la configuración esté completa, necesito dejar caer los paquetes, de lo contrario estarán en cola y se volverán a enviar más tarde, eso es algo muy malo en mi escenario. Básicamente, tengo una bandera interna para cada conexión que dice: descartar todo o reenviar todo. – viraptor

Respuesta

8

Usted puede tener el núcleo descartar los paquetes UDP mediante el establecimiento de la UDP búfer de recepción a 0.

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

Siempre que vea en condiciones de recibir los paquetes, a continuación, puede configurar el búfer para, por ejemplo, 4096 bytes .

+1

Es '& UdpBufSize', ¿no es así? ;) – viraptor

+0

¡Gracias por la captura! :) – WindsurferOak

+0

¿Hay alguna manera de descartar selectivamente paquetes de un 'sockkaddr' específico sin tener que' recv' en un búfer temporal y luego soltar el búfer? –

3

Yo prefiero descarto toda la cola de una sola vez

Dado que este es UDP estamos hablando aquí: close(udp_server_socket) y el zócalo()/bind() de nuevo?

En mi opinión debería funcionar.

+0

Esa es una solución interesante ... desafortunadamente eso no funcionará para el rango privilegiado después de una raíz cayendo (si el socket estaba vinculado antes). Lo intentaré sin embargo. – viraptor

+0

Ah, y causará errores en el cliente, lo que no puedo aceptar, lamentablemente ... – viraptor

+0

@viraptor: "causará errores en el cliente", solo si el cliente se ejecuta localmente. Y los clientes deben ignorar los errores de UDP de todos modos (además de probablemente superar un contador de errores) ya que el tipo de comunicación no es confiable de todos modos. De lo contrario, personalmente veo que no hay problema simplemente leyendo todos los mensajes: el búfer UDP recv es lo suficientemente pequeño e incluso si lo tocas en pocos megas, todavía cacahuetes para las CPU modernas. – Dummy00001

1

hombre dice about recv: el valor devuelto será 0 cuando el igual haya realizado un apagado ordenado.

Eso no se aplica a UDP. No hay una "conexión" para cerrar en UDP. Un valor de retorno de 0 es perfectamente válido, solo significa que se recibió un datagrama sin carga (es decir, solo los encabezados IP y UDP).

No estoy seguro de si su problema está o no. Realmente no entiendo a dónde vas con len = 1 cosas.

+0

No es del todo cierto. Puede llamar a connect en un socket UDP que hará que rechace paquetes de cualquier otro host: port combo y permitirá la entrega de errores de red ICMP al socket. –

+0

Connect! = Conexión sin embargo. No hay un apretón de manos, no se destruye, no se ordena ningún paquete o cualquier cosa que la mayoría de las personas asocie comúnmente con una conexión. En mi opinión, conectar es un nombre inapropiado con UDP y conduce a la confusión. – Duck

+0

No estaría de acuerdo y diría que es una conexión tan grande como 'TCP'. Recuerde que incluso en 'TCP' cada extremo mantiene su propio estado independiente y si un extremo falla, el otro nunca lo sabrá hasta que hagan dos envíos y obtengan un error de tubería roto. El concepto de "conexión" en mi mente se relaciona con la cuestión de si estás hablando de muchos a uno o uno a uno de una manera que se aplica. Por supuesto, hay argumentos para verlo de cualquier manera :-) –

Cuestiones relacionadas