ChatGPT解决这个技术问题 Extra ChatGPT

What do you use when you need reliable UDP?

If you have a situation where a TCP connection is potentially too slow and a UDP 'connection' is potentially too unreliable what do you use? There are various standard reliable UDP protocols out there, what experiences do you have with them?

Please discuss one protocol per reply and if someone else has already mentioned the one you use then consider voting them up and using a comment to elaborate if required.

I'm interested in the various options here, of which TCP is at one end of the scale and UDP is at the other. Various reliable UDP options are available and each brings some elements of TCP to UDP.

I know that often TCP is the correct choice but having a list of the alternatives is often useful in helping one come to that conclusion. Things like Enet, RUDP, etc that are built on UDP have various pros and cons, have you used them, what are your experiences?

For the avoidance of doubt there is no more information, this is a hypothetical question and one that I hoped would elicit a list of responses that detailed the various options and alternatives available to someone who needs to make a decision.

This question appears to be off-topic because it is polling for technologies
Those who thinks TCP is best in all cases, please read: en.wikipedia.org/wiki/Bandwidth-delay_product
Wikipedia has a nice table comparing various aspects of UDP, UDP Lite, TCP, Multipath TCP, SCTP, DCCP, and RUDP. SCTP supports the most features in that list.
@EugeneBeresovsky I made a little research regarding SCTP,most of the info,including from SO answers, date to 2013 and earlier.Most people wrote back then that SCTP adoption was very low.I wonder how is it today?Also,see this thread stackoverflow.com/questions/1171555/…
@MichaelIvanov Adoption is low indeed. But if you intend to use it inside your data center, you don't care about outside adoption, as long as switches and routers don't cause problems (which, in a data center, they shouldn't), and you have OS and library support, which may be an issue, as described in one of the answer in the question you linked to.

p
philant

What about SCTP. It's a standard protocol by the IETF (RFC 4960)

It has chunking capability which could help for speed.

Update: a comparison between TCP and SCTP shows that the performances are comparable unless two interfaces can be used.

Update: a nice introductory article.


That's good, I'm more interested in things that can be built on top of UDP rather than built on top of IP but it's certainly something that fits in the solution space.
SCTP has many great features (such as multihoming) and with the partial reliability extension (RFC 3758) it's an incredibly flexible option. It's included in the latest linux kernel versions, but for windows you'll have to install your own SCTP stack.
Thanks Miles, that's a useful link!
Yes... But something that is built on top of UDP rather than at the same level as UDP is likely to be easier to implement in user space, at least on Windows...
A
Andrew Edgecombe

It's difficult to answer this question without some additional information on the domain of the problem. For example, what volume of data are you using? How often? What is the nature of the data? (eg. is it unique, one off data? Or is it a stream of sample data? etc.) What platform are you developing for? (eg. desktop/server/embedded) To determine what you mean by "too slow", what network medium are you using?

But in (very!) general terms I think you're going to have to try really hard to beat tcp for speed, unless you can make some hard assumptions about the data that you're trying to send.

For example, if the data that you're trying to send is such that you can tolerate the loss of a single packet (eg. regularly sampled data where the sampling rate is many times higher than the bandwidth of the signal) then you can probably sacrifice some reliability of transmission by ensuring that you can detect data corruption (eg. through the use of a good crc)

But if you cannot tolerate the loss of a single packet, then you're going to have to start introducing the types of techniques for reliability that tcp already has. And, without putting in a reasonable amount of work, you may find that you're starting to build those elements into a user-space solution with all of the inherent speed issues to go with it.


Ok, I'll adjust the question. I'm more interested in the pros and cons of the various reliable UDP protocols out there rather than a 'use TCP' response ;)
@Andrew - it's very EASY to beat TCP in two cases: (1) your application has lighter reliability requirements than "all data, always in order, no duplicates, no excessive queueing". Or (2) you are using multicast. Reliable UDP is very common for multicast environments.
Also, TCP suffers horribly when used across a WAN connection (long haul issues). Why, simple. TCP uses windows where the packets in the window have to be ack'd. ACK protocols suffer because of latency due to line distance. Google: WAN TCP "speed of light"
@Ajaxx, you are very correct around this, however, TCP/IP does this purposely because of the last internet meltdown. If you are doing high bit rate protocol without any congestion control, well basically shame on you. If you own the network, then go wild.
"where the sampling rate is significantly higher than the nyquist rate" -- the sampling rate is always twice the nyquist rate, by definition.
L
Len Holgate

ENET - http://enet.bespin.org/

I've worked with ENET as a reliable UDP protocol and written an asynchronous sockets friendly version for a client of mine who is using it in their servers. It works quite nicely but I don't like the overhead that the peer to peer ping adds to otherwise idle connections; when you have lots of connections pinging all of them regularly is a lot of busy work.

ENET gives you the option to send multiple 'channels' of data and for the data sent to be unreliable, reliable or sequenced. It also includes the aforementioned peer to peer ping which acts as a keep alive.


C
Chris Markle

We have some defense industry customers that use UDT (UDP-based Data Transfer) (see http://udt.sourceforge.net/) and are very happy with it. I see that is has a friendly BSD license as well.


Can you elaborate on your customers and their use cases, particularly in the defense sector? Probably not, but it's worth a shot. I've actually tossed around the idea to my superiors about UDT in a file-transfer application, but it hasn't really gone anywhere yet.
L
Len Holgate

Anyone who decides that the list above isn't enough and that they want to develop their OWN reliable UDP should definitely take a look at the Google QUIC spec as this covers lots of complicated corner cases and potential denial of service attacks. I haven't played with an implementation of this yet, and you may not want or need everything that it provides, but the document is well worth reading before embarking on a new "reliable" UDP design.

A good jumping off point for QUIC is here, over at the Chromium Blog.

The current QUIC design document can be found here.


L
Len Holgate

RUDP - Reliable User Datagram Protocol

This provides:

Acknowledgment of received packets

Windowing and congestion control

Retransmission of lost packets

Overbuffering (Faster than real-time streaming)

It seems slightly more configurable with regards to keep alives then ENet but it doesn't give you as many options (i.e. all data is reliable and sequenced not just the bits that you decide should be). It looks fairly straight forward to implement.


I was looking at this but there does not appear to be many implementations. Got a recommendation ?
No, sorry. I didn't end up using it in the end and was always going to do an implementation from scratch.
s
smo

As others have pointed out, your question is very general, and whether or not something is 'faster' than TCP depends a lot on the type of application.

TCP is generally as fast as it gets for reliable streaming of data from one host to another. However, if your application does a lot of small bursts of traffic and waiting for responses, UDP may be more appropriate to minimize latency.

There is an easy middle ground. Nagle's algorithm is the part of TCP that helps ensure that the sender doesn't overwhelm the receiver of a large stream of data, resulting in congestion and packet loss.

If you need the reliable, in-order delivery of TCP, and also the fast response of UDP, and don't need to worry about congestion from sending large streams of data, you can disable Nagle's algorithm:

int opt = -1;
if (setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, (char *)&opt, sizeof(opt)))
  printf("Error disabling Nagle's algorithm.\n");

As I said, assuming TCP is at one end of the scale and UDP at the other, what else is there.
If you want to be pedantic, most of the discussed protocols are built on top of UDP.
The assumption that TCP is at one end and UDP is at the other end is false. e.g. UDP has no flow control, you can easily send packets too fast, causing a router inbetween to drop all of them. Then what do you do ? Ignore the lost packets or resend them ? Resending them and you'll end up reimplementing TCP more or less. Another option for reliable communication is SCTP.
A fast response doesn't necessarily equal a high throughput.
I disagree. When nagle is used on TCP based protocols with lots of smaller packets, it'll merge them together and create more larger packets. It causes some slight delay in sending so latecy may increase very slightly. However, throughput can be lower with nagle off because more packets = more packet headers = greater overhead. Packets being dropped on a LAN is usually more to do with input buffers filling. If you have lots of clients sending data to the same host it may make zero difference. I don't believe turning off and on nagle is going to effect it in practice.
1
17 of 26

If you have a situation where a TCP connection is potentially too slow and a UDP 'connection' is potentially too unreliable what do you use? There are various standard reliable UDP protocols out there, what experiences do you have with them?

The key word in your sentence is 'potentially'. I think you really need to prove to yourself that TCP is, in fact, too slow for your needs if you need reliability in your protocol.

If you want to get reliability out of UDP then you're basically going to be re-implementing some of TCP's features on top of UDP which will probably make things slower than just using TCP in the first place.


Yes, Andrew Edgecombe said as much, but, as I said, I'm interested in the pros and cons of WHAT alternatives there are. Without that list of alternatives and their pros and cons then it's hard to decide what's best.
Given a known reliablity function, sometimes a UDP stream can be hand-tuned to outrace the TCP stream in hte OS. Rare though.
@17 of 26, I agree to Len Holgate, TCP will be slower than reliable UDP in some circumstances. Like high BDP network, suppose you have 1 Gbps internet connection from China to NewYork, I am sure TCP will suck to use almost all of 1 Gbps speed. TCP is better for most of connections on earth, but not for network with High Bandwidth Delay Product.
b
bortzmeyer

Protocol DCCP, standardized in RFC 4340, "Datagram Congestion Control Protocol" may be what you are looking for.

It seems implemented in Linux.


b
bortzmeyer

May be RFC 5405, "Unicast UDP Usage Guidelines for Application Designers" will be useful for you.


p
philant

Did you consider compressing your data ?

As stated above, we lack information about the exact nature of your problem, but compressing the data to transport them could help.


Especially with modern compression libraries. Some are as fast as a memcpy. e.g. lz4.
E
Engineer

RUDP. Many socket servers for games implement something similar.


m
mrKirushko

It is hard to give a universal answer to the question but the best way is probably not to stay on the line "between TCP and UDP" but rather to go sideways :).

A bit more detailed explanation:

If an application needs to get a confirmation response for every piece of data it transmits then TCP is pretty much as fast as it gets (especially if your messages are much smaller than optimal MTU for your connection) and if you need to send periodic data that gets expired the moment you send it out then raw UDP is the best choice for many reasons but not particularly for speed as well.

Reliability is a more complex question, it is somewhat relative in both cases and it always depends on a specific application. For a simple example if you unplug the internet cable from your router then good luck keeping reliably delivering anything with TCP. And what even worse is that if you don't do something about it in your code then your OS will most likely just block your application for a couple of minutes before indicating an error and in many cases this delay is just not acceptable as well.

So the question with conventional network protocols is generally not really about speed or reliability but rather about convenience. It is about getting some features of TCP (automatic congestion control, automatic transmission unit size adjustment, automatic retransmission, basic connection management, ...) while also getting at least some of the important and useful features it misses (message boundaries - the most important one, connection quality monitoring, multiple streams within a connection, etc) and not having to implement it yourself.

From my point of view SCTP now looks like the best universal choice but it is not very popular and the only realistic way to reliably pass it across the Internet of today is still to wrap it inside UDP (probably using sctplib). It is also still a relatively basic and compact solution and for some applications it may still be not sufficient by itself.

As for the more advanced options, in some of the projects we used ZeroMQ and it worked just fine. This is a much more of a complete solution, not just a network protocol (under the hood it supports TCP, UDP, a couple of higher level protocols and some local IPC mechanisms to actually deliver messages). Since a couple of releases its initial developer has switched his attention to his new NanoMSG and currently the newest NNG libraries. It is not as thoroughly developed and tested and it is not very popular but someday it may change. If you don't mind the CPU overhead and some network bandwidth loss then some of the libraries might work for you. There are some other network-oriented message exchange libraries available as well.


Nice answer. I agree, SCTP is a good choice and flexible. I've used it via sctplib and a home brewed implementation for WebRTC data channel work and it's good.
r
rdalmeida

You should check MoldUDP, which has been around for decades and it is used by Nasdaq's ITCH market data feed. Our messaging system CoralSequencer uses it to implement a reliable multicast event-stream from a central process.

Disclaimer: I'm one of the developers of CoralSequencer


k
kushan singh

The best way to achieve reliability using UDP is to build the reliability in the application program itself( for example, by adding acknowledgment and retransmission mechanisms)


关注公众号,不定期副业成功案例分享
Follow WeChat

Success story sharing

Want to stay one step ahead of the latest teleworks?

Subscribe Now