为什么在使用套接字在Windows 7而不是XP上接收UDP广播时,我看到重复的数据包?

时间:2011-12-13 22:33:20

标签: c# .net sockets windows-7 windows-xp

让我先说一下,套接字编程对我来说相当新鲜。此外,我问的代码已经工作了几年,我讨论的问题才开始,当我们从支持Windows XP改为Windows 7时。

我正在开发一个发送和接收网络数据包的C#应用​​程序。它是一种网络嗅探器类型的应用程序,因此数据完整性非常重要。自从我们从 Windows XP 迁移到 Windows 7 以来,当我们使用UDP广播(255.255.255.255)数据包时,我们会收到两次数据包。 (即我发送610个数据包,我收到1220个数据包)。

我已经使用WireShark验证了数据包只被接收一次。此外,我们还有一些旧的C ++套接字代码已被.NET代码替换。较旧的C ++代码不表示重复。这两个都表示发送了610个数据包,收到了610个数据包。

代码是高度线程化的,并且在各个类之间分开,但是将一些部分放在一起,接收代码如下所示:

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

然后在负责阅读的代码中......

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

所以我的问题是,Windows XP和Windows 7之间的.NET套接字API会导致这种行为的变化是什么?我已阅读线程,表明存在差异,但没有这样的。跟踪代码使我认为它与Receive()类上Socket类的行为有关,可能有所不同。任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:5)

根据规范,这是预期的行为。

http://msdn.microsoft.com/en-us/library/system.net.sockets.iocontrolcode(v=vs.110).aspx表示ReceiveAll等于Winsock 2 SIO_RCVALL常量。

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

  

在Windows Server 2008及更早版本中,SIO_RCVALL IOCTL设置会   不捕获从网络接口发出的本地数据包。这个   包含在另一个接口上接收并转发出去的数据包   为SIO_RCVALL IOCTL指定的网络接口。

     

在Windows 7上   和Windows Server 2008 R2一样,这改变了本地数据包   发送出的网络接口也被捕获。这包括   在另一个接口上接收的数据包然后转发出去   使用SIO_RCVALL IOCTL绑定到套接字的网络接口。