views:

2377

answers:

15

I'm working on a .net solution that is run completely inside a single network. When users make a change to the system, I want to launch an announcement and have everyone else hear it and act accordingly. Is there a way that we can broadcast out messages like this (like UDP will let you do) while keeping guaranteed delivery (like TCP)?

This is on a small network (30ish clients), if that would make a difference.

A: 

do a RDP multicast.

Tim Williscroft
There is no TCP multicast, I'd vote this down, but I don't have enough reputation.
tialaramex
A: 

What you can do is that after the broadcast have the clients initiate the tcp connections. Otherwise you just have to keep a list of all clients and initiate the connections to each client yourself.

paan
A: 

I think there are three options, broadly speaking:

  1. Instead of broadcasting UDP, you could create an entity (a thread, process, server, service, or whatever the thing is that exists in your solution) that keeps a list of subscribers and sends unicast UDP messages to them.
  2. Use UDP multicast, but you'll have to write some sort of mechanism that would take care of reliable delivery for you (i.e., retries, timeouts, etc). This also means you have to get a reply from your clients.
  3. If you're not afraid of experimental transport protocols, you might look here for suggestions.,
Ben Collins
+5  A: 

You could use Spread to do group communication.

Cagatay
I'll second this. Using somebody else's library is your best bet to get this correct.
Jay Kominek
+1  A: 

You could implement your own TCP-like behaviour at the application layer.

So for instance, you'd send out the UDP broadcast, but then expect a reply response from each host. If you didn't get a response within X seconds, then send another and so on until reaching some sort of threshold. If the threshold is reached (i.e. the host didn't respond at all), then report an error.

To do this though, you'd need a pre-defined list of hosts to expect the responses back from.

Steve M
+8  A: 

Almost all games have a need for the fast-reacting properties (and to a lesser extent, the connectionless properties) of UDP and the reliability of TCP. What they do is they build their own reliable protocol on top of UDP. This gives them the ability to just burst packets to whereever and optionally make them reliable, as well.

The reliable packet system is usually a simple retry-until-acknowledged system simpler than TCP but there are protocols which go way beyond what TCP can offer.

Your situation sounds very simple. You'll probably be able to make the cleanest solution yourself - just make every client send back an "I heard you" response and have the server keep trying until it gets it (or gives up).

If you want something more, most custom protocol libraries are in C++, so I am not sure how much use they'll be to you. However, my knowledge here is a few years old - perhaps some protocols have been ported over by now. Hmm... RakNet and enet are two C/C++ libraries that come to mind.

Sander
+9  A: 

Take a look at sctp which has a combination of tcp and udp features. There is a windows implementation available.

epatel
A: 

Yoy should take a look at the Norm (NACK-Oriented Reliable Multicast) specification. You can find information about Norm here.

The NORM protocol is designed to provide end-to-end reliable transport of bulk data objects or streams over generic IP multicast routing and forwarding services. NORM uses a selective, negative acknowledgement (NACK) mechanism for transport reliability and offers additional protocol mechanisms to conduct reliable multicast sessions with limited "a priori" coordination among senders and receivers

It somewhat very well known in the military world.

Norm specs.

Norm Source

Jorge Córdoba
+3  A: 

@epatel - I second the SCTP suggestion (I voted up, but can't comment yet so additional stuff here).

SCTP has many great features and flexibility. You can sub-divide your connection into multiple streams, and choose the reliablity of each and whether it is ordered or not. Alternatively, with the Partially Reliability extension, you can control reliability on a per message basis.

Andrew Johnson
+1  A: 

Broadcast is not what you want. Since there could and probably will be devices attached to this network which don't care about your message, you should use Multicast. Unlike broadcast messages, which must be sent to and processed by every client on the network, Multicast messages are delivered only to interested clients (ie those which have some intention to receive this particular type of message and act on it).

If you later scale this system up so that it needs to be routed over a large network, multicast can scale to that, whereas broadcast won't, so you gain a scalability benefit which you might appreciate later. Meanwhile you eliminate unnecessary overhead in switches and other devices that don't need to see these "something changed" messages.

tialaramex
A: 

You might want to look into RFC 3208 "PGM Reliable Transport Protocol Specification".

Here is the abstract:

Pragmatic General Multicast (PGM) is a reliable multicast transport
protocol for applications that require ordered or unordered,
duplicate-free, multicast data delivery from multiple sources to
multiple receivers. PGM guarantees that a receiver in the group either receives all data packets from transmissions and repairs, or is able to detect unrecoverable data packet loss. PGM is specifically intended as a workable solution for multicast applications with basic reliability requirements. Its central design goal is simplicity of operation with due regard for scalability and network efficiency.

Cayle Spandon
A: 

Why build something from scratch if you can use library? Especially for such small project?

Try use Emcaster which itself using reliable multicast messaging - PGM, is written in .NET and with full source. You will get nice pub/sub engine with topic filtering readily available. Or you can learn from code how to do it and base your own extension on it.

Libor
A: 

I think the most irritating feature of TCP in these scenarios is the ability/way of sorting incoming packets to their original order - the concept of a stream. You cannot read a byte until the byte before it arrived.

If you can live without it, you have your chance to have your protocol, fast and reliable, but not for ordering of packets! It's simply impossible to manage both of them, because you cannot order your bytes until you receive an other copy of a lost packet, that's the main tradeoff.

Szundi
A: 

Create a TCP server. Have each client connect. In your TCP protocol with the clients, create each packet with a 2-byte prefix of the total size of the following message.

Clients then call read(max_size=2) on the socket to determine the size of the next message, and then read(max_size=s) to collect the message.

You get reliable, ordered messages, simple. You don't need a messaging framework for this one.

Matthew Herrmann
A: 

You could use a Message Broker, such as ActiveMQ.
Publish your messages to a topic and have the clients register durable subscriptions to the topic, so that they won't miss any messages even if they are not online.

Apache ActiveMQ is a message broker written in Java together with a full JMS client. However Apache ActiveMQ is designed to communicate over a number of protocols such as Stomp and OpenWire together with supporting a number of different language specific clients.

Client platform support includes c# and .net

crowne