2011-12-13 4 views
5

Pozwólcie mi stwierdzić z góry, że programowanie gniazd jest dla mnie całkiem nowe. Kod, o który pytam, działał przez kilka lat, a problem, który omawiam, zaczął się dopiero, gdy zmieniliśmy obsługę systemu Windows XP na Windows 7.Dlaczego widzę duplikaty pakietów podczas korzystania z gniazd do odbierania transmisji UDP w systemie Windows7, ale nie XP?

Pracuję nad aplikacją C#, która wysyła i odbiera pakiety sieciowe . Jest to rodzaj aplikacji typu sniffer sieci, więc integralność danych jest bardzo ważna. Od czasu migracji z systemu Windows XP do Windows 7, kiedy przesyłamy pakiety UDP (255.255.255.255), otrzymujemy dwa pakiety. (tj. wysyłam 610 pakietów, otrzymuję 1220 pakietów).

Weryfikowałem za pomocą WireSharka, że ​​pakiety są odbierane tylko raz. Mamy również kilka starszych kodów gniazd C++, które zostały zastąpione przez kod .NET. Starszy kod C++ nie wskazuje duplikatów. Oba oznaczają 610 wysłanych pakietów, 610 odebranych pakietów.

Kod jest wysoce gwintowane i rozłam wśród różnych klas, ale oddanie niektóre kawałki razem, kod otrzymywać wygląda następująco:

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

a następnie w kodzie odpowiedzialnym za czytanie ...

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

Moje pytanie brzmi: co zmieniło się w interfejsie API gniazd .NET między Windows XP i Windows 7, które spowodowałoby to zachowanie? Czytałem wątki wskazujące na różnice, ale nic takiego. Śledzenie kodu sprawia, że ​​myślę, że ma to związek z zachowaniem metody Receive() na klasie Socket, która może być inna. Każda pomoc będzie doceniona!

Odpowiedz

4

Według specyfikacji jest to oczekiwane zachowanie.

mówi, że ReceiveAll jest równy stałej Winsock 2 SIO_RCVALL.

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

W systemie Windows Server 2008 i wcześniej, ustawienie SIO_RCVALL IOCTL byłoby nie uchwycić lokalne pakiety wysyłane z interfejsem sieciowym. Ta zawierała pakiety odebrane na innym interfejsie i przekazała interfejs sieciowy określony w IOCTL SIO_RCVALL.

W systemie Windows 7 i Windows Server 2008 R2 zmieniono to, tak że przechwytywane są również lokalne pakiety wysyłane z interfejsu sieciowego. Obejmuje to pakiety otrzymane na innym interfejsie, a następnie przekazane interfejs sieciowy powiązany z gniazdem za pomocą SIO_RCVALL IOCTL.

+0

Dzięki. Natknąłem się również na ten artykuł. To z pewnością wyjaśnia, dlaczego widzę zachowanie podczas przesyłania i odbierania na tym samym komputerze. Jednak nadal obserwuję to zachowanie na komputerze odbierającym podczas przesyłania z innego komputera. Czy może mieć coś wspólnego z tym, jak XP i Win7 radzą sobie z emisjami do 255.255.255.255? Moje surowe gniazdo zbiera również w usłudze Windows, a następnie używa 127.0.0.1 dla IPC do przesyłania danych do aplikacji frontowej. Być może to też złapie? – bporter

+0

Przepraszam, nie przeczytałem dokładnie tego pytania, myślę, że powinienem je usunąć. Więc kilka nowych myśli: Jaki adres jesteś wiążący gniazdo do? Czy jest aktywne jakieś mostkowanie IP lub routing? Mówiąc o IPC do 127.0.0.1, nie przesyłasz pakietów IP na front end, czy też nie? –

+0

Nie usunąłabym odpowiedzi. Podałeś kilka bardzo użytecznych informacji. Muszę skontaktować się z jednym z pozostałych inżynierów, aby uzyskać ostateczne odpowiedzi na te pytania. Myślę, że znam odpowiedzi, ale nie byłem na tym projekcie wystarczająco długo, aby powiedzieć na pewno. – bporter

Powiązane problemy