Let me state up front, that sockets programming is fairly new to me. Also, the code I'm asking about has worked for several years and the problem I discuss only began when we changed from supporting Windows XP to Windows 7.
I am working on a C# application that sends and receives network packets. It's sort of a network sniffer type application, so data integrity is very important. Ever since we migrated from Windows XP to Windows 7, when we UDP Broadcast (255.255.255.255) packets, we receive the packets twice. (i.e. I send 610 packets, I receive 1220 packets).
I have verified with WireShark that the packets are only being received once. Also, we have some older C++ sockets code that had been replaced by .NET code. The older C++ code does not indicate duplicates. These both indicate 610 packets sent, 610 packets received.
The code is highly threaded and split among various classes, but putting some of the pieces together, the receive code looks like the following:
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 */ );
And then in the code responsible for reading...
byte[] buffer = new byte[ 65536 ];
int read = _device.Receive( buffer );
if (read > 0)
{
_packet = new byte[ size ];
_packet.BlockCopy( buffer, offset, size );
}
So my question is, what changed with the .NET sockets API between Windows XP and Windows 7 that would cause this behavior? I have read threads that indicate there are differences, but nothing like this. Tracing through the code makes me think that it has to do with the behavior of the Receive()
method on the Socket
class that may be different. Any help would be appreciated!
According to the spec this is expected behaviour.
http://msdn.microsoft.com/en-us/library/system.net.sockets.iocontrolcode(v=vs.110).aspx says that ReceiveAll equals to the Winsock 2 SIO_RCVALL constant.
http://msdn.microsoft.com/en-us/library/windows/desktop/ee309610(v=vs.85).aspx says:
On Windows Server 2008 and earlier, the SIO_RCVALL IOCTL setting would not capture local packets sent out of a network interface. This included packets received on another interface and forwarded out the network interface specified for the SIO_RCVALL IOCTL.
On Windows 7 and Windows Server 2008 R2 , this was changed so that local packets sent out of a network interface are also captured. This includes packets received on another interface and then forwarded out the network interface bound to the socket with SIO_RCVALL IOCTL.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With