可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.
回答1:
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.
回答2:
Take a look at sctp which has a combination of tcp and udp features. There is a windows implementation available.
回答3:
You could use Spread to do group communication.
回答4:
@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.
回答5:
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.
回答6:
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.
回答7:
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
回答8:
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.
回答9:
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.
回答10:
You'd definitely want to look into Pragmatic General Multicast:
While TCP uses ACKs to acknowledge groups of packets sent (something that would be uneconomical over multicast), PGM uses the concept of Negative Acknowledgements (NAKs).
For further G-diving, the term you're looking for is reliable multicast. Also take a look at Multipath TCP.
回答11:
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.
回答12:
I think there are three options, broadly speaking:
- 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.
- 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.
- If you're not afraid of experimental transport protocols, you might look here for suggestions.,
回答13:
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
回答14:
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.
回答15:
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.
回答16: