2011-12-13 13 views
5

Permítanme afirmar desde el principio, que la programación de sockets es bastante nueva para mí. Además, el código que pregunto ha funcionado durante varios años y el problema que analizo solo comenzó cuando cambiamos de Windows XP a Windows 7.¿Por qué veo paquetes duplicados cuando uso sockets para recibir transmisiones UDP en Windows7 pero no en XP?

Estoy trabajando en una aplicación C# que envía y recibe paquetes de red . Es una especie de aplicación de tipo sniffer de red, por lo que la integridad de los datos es muy importante. Desde que migramos de Windows XP a Windows 7, cuando recibimos paquetes UDP Broadcast (255.255.255.255), recibimos los paquetes dos veces. (es decir, envío 610 paquetes, recibo 1220 paquetes).

He verificado con WireShark que los paquetes solo se reciben una vez. Además, tenemos un código anterior de sockets de C++ que había sido reemplazado por el código .NET. El código anterior de C++ no indica duplicados. Ambos indican 610 paquetes enviados, 610 paquetes recibidos.

El código es altamente roscado y dividida entre varias clases, pero poniendo algunas de las piezas, el código de recepción tiene el siguiente aspecto:

public class RawSocket : Socket 
{ 
    public RawSocket(IPAddress address, int receiveBufferSize, bool receiveAll) 
     : base(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP) 
    { 
     Bind(new IPEndPoint(address, 0)); 

     ReceiveBufferSize = receiveBufferSize; 

     ReceiveTimeout = 500; // half-a-second 

     if (receiveAll) { 
      byte[] incoming = BitConverter.GetBytes(1); 
      byte[] outgoing = BitConverter.GetBytes(1); 
      IOControl(IOControlCode.ReceiveAll, incoming, outgoing); 
     } 
    } 
} 

_device = new RawSocket(/* IP Address Specified Here */); 

Y luego en el código responsable de leer ...

byte[] buffer = new byte[ 65536 ]; 
int read = _device.Receive(buffer); 
if (read > 0) 
{ 
    _packet = new byte[ size ]; 
    _packet.BlockCopy(buffer, offset, size); 
} 

Así que mi pregunta es, ¿qué cambió con la API de sockets .NET entre Windows XP y Windows 7 que podría causar este comportamiento? He leído hilos que indican que hay diferencias, pero nada como esto. Rastrear el código me hace pensar que tiene que ver con el comportamiento del método Receive() en la clase Socket que puede ser diferente. ¡Cualquier ayuda sería apreciada!

Respuesta

4

De acuerdo con la especificación, este es el comportamiento esperado.

http://msdn.microsoft.com/en-us/library/system.net.sockets.iocontrolcode(v=vs.110).aspx dice que ReceiveAll es igual a la constante Winsock 2 SIO_RCVALL.

http://msdn.microsoft.com/en-us/library/windows/desktop/ee309610(v=vs.85).aspx dice:

En Windows Server 2008 y versiones anteriores, la configuración SIO_RCVALL IOCTL sería no capturar los paquetes enviados locales de una interfaz de red. Este incluyó paquetes recibidos en otra interfaz y reenvió la interfaz de red especificada para SIO_RCVALL IOCTL.

En Windows 7 y Windows Server 2008 R2, esto se modificó para que también se capturen los paquetes locales enviados desde una interfaz de red. Esto incluye los paquetes recibidos en otra interfaz y luego reenviados a la interfaz de red vinculada al socket con SIO_RCVALL IOCTL.

+0

Gracias. Me encontré con ese artículo también. Ciertamente explica por qué veo el comportamiento cuando estoy transmitiendo y recibiendo en la misma computadora. Sin embargo, todavía observo este comportamiento en la computadora receptora cuando transmite desde otra computadora. ¿Podría tener algo que ver con cómo XP y Win7 se ocupan de las transmisiones a 255.255.255.255? Además, mi socket sin procesar se está recopilando en un servicio de Windows y luego usando 127.0.0.1 para que IPC transmita los datos a la aplicación de front-end. ¿Tal vez también capta eso? – bporter

+0

Lo siento, no leí su pregunta con cuidado, creo que debería eliminarla. Entonces, algunos pensamientos nuevos: ¿A qué dirección está vinculando el socket? ¿Hay algún tipo de puente de IP o enrutamiento activo? Cuando se habla de IPC a 127.0.0.1, no solo reenvía los paquetes de IP a la interfaz, ¿o sí? –

+0

No eliminaría la respuesta. Usted ha proporcionado información muy útil. Tendré que contactarme con uno de los otros ingenieros para obtener respuestas definitivas a esas preguntas. Creo que sé las respuestas, pero no he estado en este proyecto el tiempo suficiente para decirlo con seguridad. – bporter

Cuestiones relacionadas