2011-12-13 9 views
5

Lasciatemi dire in anticipo, che la programmazione delle prese è abbastanza nuova per me. Inoltre, il codice che sto chiedendo ha funzionato per diversi anni e il problema discusso è iniziato solo quando abbiamo cambiato il supporto da Windows XP a Windows 7.Perché visualizzo pacchetti duplicati quando si utilizzano socket per ricevere trasmissioni UDP su Windows 7 ma non su XP?

Sto lavorando a un'applicazione C# che invia e riceve pacchetti di rete . È una specie di applicazione di sniffer di rete, quindi l'integrità dei dati è molto importante. Da quando abbiamo migrato da a Windows XP a Windows 7, quando trasmettiamo i pacchetti UDP Broadcast (255.255.255.255), riceviamo i pacchetti due volte. (Ad esempio, invio 610 pacchetti, ricevo 1220 pacchetti).

Ho verificato con WireShark che i pacchetti vengono ricevuti una sola volta. Inoltre, abbiamo un vecchio codice di socket C++ che è stato sostituito dal codice .NET. Il vecchio codice C++ non indica duplicati. Entrambi indicano 610 pacchetti inviati, 610 pacchetti ricevuti.

Il codice è altamente filettato e diviso tra le varie classi, ma mettendo alcuni dei pezzi insieme, il codice di ricezione appare come il seguente:

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 */); 

E poi nel codice responsabile per la lettura ...

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

Quindi la mia domanda è, cosa è cambiato con .NET socket API tra Windows XP e Windows 7 che potrebbe causare questo comportamento? Ho letto i thread che indicano che ci sono differenze, ma niente di simile. Tracciare il codice mi fa pensare che abbia a che fare con il comportamento del metodo Receive() sulla classe Socket che potrebbe essere differente. Qualsiasi aiuto sarebbe apprezzato!

risposta

4

Secondo le specifiche questo comportamento è previsto.

http://msdn.microsoft.com/en-us/library/system.net.sockets.iocontrolcode(v=vs.110).aspx dice che ReceiveAll è uguale alla costante SIO_RCVALL di Winsock 2.

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

In Windows Server 2008 e precedenti, l'impostazione SIO_RCVALL IOCTL sarebbe non catturare i pacchetti locali inviati da un'interfaccia di rete. Questo pacchetto includeva i pacchetti ricevuti su un'altra interfaccia e inoltrava l'interfaccia di rete specificata per SIO_RCVALL IOCTL.

Su Windows 7 e Windows Server 2008 R2, questo è stato modificato in modo da acquisire anche i pacchetti locali inviati da un'interfaccia di rete. Ciò include i pacchetti ricevuti su un'altra interfaccia e quindi inoltrata all'interfaccia di rete associata al socket con IIOCCO SIO_RCVALL.

+0

Grazie. Mi ero imbattuto anche in quell'articolo. Certamente spiega perché vedo il comportamento quando sto trasmettendo e ricevendo sullo stesso computer. Tuttavia, osservo ancora questo comportamento sul computer ricevente durante la trasmissione da un altro computer. Potrebbe forse avere qualcosa a che fare con il modo in cui XP e Win7 gestiscono le trasmissioni su 255.255.255.255? Inoltre, il mio socket raw si sta raccogliendo in un servizio Windows e quindi utilizzando 127.0.0.1 per IPC per trasmettere i dati all'applicazione front-end. Forse sta prendendo anche quello? – bporter

+0

Scusa, non ho letto abbastanza attentamente la tua domanda, penso che dovrei eliminarla. Quindi alcuni nuovi pensieri: a quale indirizzo stai vincolando il socket? C'è qualche tipo di bridging o routing IP attivo? Quando parli di IPC su 127.0.0.1 non devi semplicemente inoltrare i pacchetti IP al front end o no? –

+0

Non cancellerei la risposta. Hai fornito alcune informazioni molto utili. Dovrò prendere uno degli altri ingegneri per ottenere risposte definitive a quelle domande. Penso di conoscere le risposte, ma non sono stato su questo progetto abbastanza a lungo da poterlo dire con certezza. – bporter

Problemi correlati