Possible bug in .NET multicast socket?

T

Terry

I've got a strange problem receiving multicast packets in a C#
application. What's strange is that it works *sometimes* but not always.

I create a socket, call bind(), set the multicast socket option and then
fire off a thread that calls "receiveFrom()" in a loop. This works
sometimes, but other times it'll get into a funk where the
"receiveFrom()" call doesn't return even though a packet trace capture
(Ethereal) shows that the multicast packet was received.

Here's where I'm creating the socket and setting up the thread:

private void createListener()
{
createListenerSocket();

_listenerThread = new Thread(new ThreadStart(listenerProc));
_listenerThread.Name = "Multicast Listener";
_listenerThread.IsBackground = true;
_fRunning = true;
_listenerThread.Start();
}

private void createListenerSocket()
{
IPEndPoint iep = new IPEndPoint(IPAddress.Any, _nGroupPort);
int nTTL = AppSettings.Instance.LAN.MulticastTTL;
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,
ProtocolType.Udp);
_socket.Bind(iep);
_socket.SetSocketOption(SocketOptionLevel.IP,
SocketOptionName.AddMembership,
new MulticastOption(_groupAddress));
_socket.SetSocketOption(SocketOptionLevel.IP,
SocketOptionName.MulticastTimeToLive, nTTL);
}


And here's the loop where I'm receiving and processing the packets.

private void listenerProc()
{
IPEndPoint iep = new IPEndPoint(IPAddress.Any, 0);
EndPoint ep = iep;
byte[] recvBuff = new byte[8192];
int nBytes;
while (_fRunning)
{
nBytes = _socket.ReceiveFrom(recvBuff, ref ep);

if (isFromMyself((IPEndPoint)ep))
{
logMessage("Packet was sent by me. Ignoring.",
TraceLevel.Verbose);
continue;
}

logMessage("listenerProc - Received " + nBytes + " bytes from "
+ ep.ToString(), TraceLevel.Verbose);
IPEndPoint iepRemote = (IPEndPoint)ep;
processPacket(getMessageBytes(recvBuff, nBytes), iepRemote);
}
}

So, to reiterate, I've verified that the packet is being recieved by my
NIC and is being sent to the proper multicast address. In my case the
address is "230.2.1.75" with a TTL of 2. But, most of the time, the
"_socket.ReceiveFrom()" never returns. Sometimes this works just fine.

So, if the multicast packet is indeed making it to my machine, verfied
by a packet sniffer, and my "ReceiveFrom()" call never returns, wouldn't
that indicate a problem in the .NET socket code?


Thanks,
Terry
 
O

Oliver Sturm

Terry said:
So, if the multicast packet is indeed making it to my machine, verfied
by a packet sniffer, and my "ReceiveFrom()" call never returns, wouldn't
that indicate a problem in the .NET socket code?

I guess not, as usual :) I'm sorry if my reply is not particularly
helpful, but I thought I'd tell you that I have an application that
works very similarly to your code, and it works fine. The main
difference I saw was that I use asynchronous receiving instead of the
blocking variant, so I call BeginReceiveFrom instead of ReceiveFrom.
Maybe you could try changing your approach to see if this makes any
difference?


Oliver Sturm
 
T

Terry

Oliver said:
I guess not, as usual :) I'm sorry if my reply is not particularly
helpful, but I thought I'd tell you that I have an application that
works very similarly to your code, and it works fine. The main
difference I saw was that I use asynchronous receiving instead of the
blocking variant, so I call BeginReceiveFrom instead of ReceiveFrom.
Maybe you could try changing your approach to see if this makes any
difference?


Oliver Sturm

Well, I may have found the culprit here and I have to say I'm a little
surprised by what I found. When handling an incoming message, there was
some code that was attempting to access a property of a null reference,
which was causing the receive thread to die. What surprises me is that
accessing a null reference would not display an "Unhandled exception"
error of any kind. The thread just silently goes away without a peep.

I did some testing and it appears that the .NET Framework "Unhandled
exception" dialog only gets displayed if something bad happens on the
application's main thread.

I've read a fair amount about threading in .NET and I don't think I've
ever heard of that before. I was discounting thread death because I
never saw an error message being displayed. :-/ Stupid me.

Thanks for the reply!

Terry
 
O

Oliver Sturm

Terry said:
I did some testing and it appears that the .NET Framework "Unhandled
exception" dialog only gets displayed if something bad happens on the
application's main thread.

I've read a fair amount about threading in .NET and I don't think I've
ever heard of that before. I was discounting thread death because I
never saw an error message being displayed. :-/ Stupid me.

You can configure the debugger's behaviour for exceptions in Visual
Studio. From the Debug menu, select Exceptions. The useful thing is that
you can configure the debugger to break when an exception is thrown. I'm
quite sure that this will get a break for thread exceptions as well.



Oliver Sturm
 
T

Terry

Oliver said:
You can configure the debugger's behaviour for exceptions in Visual
Studio. From the Debug menu, select Exceptions. The useful thing is that
you can configure the debugger to break when an exception is thrown. I'm
quite sure that this will get a break for thread exceptions as well.



Oliver Sturm

I guess I didn't make it clear that the lack of an exception is when I
was NOT running in a debugger. So, I would do a release build and
distribute the application and because of the lack of any exception I
was assuming that the thread wasn't dying, which caused my confusion.
(Really, I know better, but for whatever reason I didn't listen to myself)

The fault is entirely my own because I didn't wrap the thread's code in
a try catch, but I do have a top-level exception handler which didn't
catch it either. If you don't wrap your thread's code in a try/catch,
is there something in .NET that's catching it and silently ignoring it?

Terry
 
O

Oliver Sturm

Terry said:
The fault is entirely my own because I didn't wrap the thread's code in
a try catch, but I do have a top-level exception handler which didn't
catch it either. If you don't wrap your thread's code in a try/catch,
is there something in .NET that's catching it and silently ignoring it?

You can catch this kind of exception if you handle the
AppDomain.UnhandledException event.

In .NET 2.0, there has been a change to the standard behaviour of the
CLR, which will make your application terminate after encountering an
unhandled exception in a thread (and raising the app domain event, as it
did in 1.1).


Oliver Sturm
 
T

Terry

Oliver said:
You can catch this kind of exception if you handle the
AppDomain.UnhandledException event.

In .NET 2.0, there has been a change to the standard behaviour of the
CLR, which will make your application terminate after encountering an
unhandled exception in a thread (and raising the app domain event, as it
did in 1.1).


Oliver Sturm

Thank you Oliver! You've been very helpful.

Terry
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top