views:

131

answers:

0

Hi folks,

I made an application using boost.Asio using UDP multicast. I don't think the question is really specific to boost.Asio but to sockets programming in general, since boost.Asio's network facilities are mostly wrappers to socket functions.

I constructed the application based on the multicast examples ( http://www.boost.org/doc/libs/1_44_0/doc/html/boost_asio/example/multicast/receiver.cpp and ~/sender.cpp) and I deployed it on several machines running on Windows, Linux and a Mac with OSX Leopard. I'm very pleased that multicasting on all platforms works out of the box with the code derived from the examples.

Where I run into problems, is when I disconnect the network cable. Of course, disconnecting the cable will always cause problems ;) but there are subtle differences that drive me crazy.

My testing setup is always as follows: One machine running a sender and a receiver, to see if the same machine receives its own multicast, and another machine running only the receiver. I pull the network cord on the machine running the sender and the receiver.

Observed behavior:

-Obviously the machine where the receiver runs doesn't receive any more messages. That was to be expected ;)

-When the machine where the network cable is unplugged runs windows, the sender continues to send and the receiver on the same machine continues to receive. No errors detected. It seems windows has an intrinsic fallback to loopback?

-When the machine where the network cable is unplugged runs Mac OSX, the sender continues to send with no error message displayed, but the receiver on the same machine doesn't receive anymore. Before you ask, I checked NOT to set the disable loopback option.

-When the machine where the network cable is unplugged runs Linux, the sender fails with a boost::error "Network is unreachable". Obviously, since the sender can't send the data, the receiver doesn't receive anything anymore.

For Linux, I can fake the behavior of Windows by catching the "unreachable" error (or catching a wrong number of bytes written) and setting a flag in my code, subsequently sending all data to 127.0.0.1 instead of the multicast address. I regularly check if a send_to on the multicast endpoint still yields an error to detect a network reconnect and go back to multicasting. This works like a charm because the receiver is bind() to inaddr_any and thus listens on 127.0.0.1 also.

For Mac OSX I have no means of noticing when the network becomes unreachable to keep up the service for the receiver on the local machine.

I observed that on Mac OSX I get a "Network is unreachable" error momentarily once when the network cable is re-plugged and DHCP hasn't yet acquired a new IP address.

So basically: How can I achieve that on MacOSX the local client can still receive from the local sender? Either by detecting a network loss like I do on Linux or by tricking it into behaving like Windows.

Any advise by people who have a deeper insight into network programming than i have, is greatly appreciated.