Should my server use both TCP and UDP?
Asked Answered
A

6

12

I'm writing a client/server application and really can't find guides that fit my need. Doing it on my own leads me to many design flaws before I've even begun. For instance the server should update every client as to its state many times each second. I assumed I couldn't update every client individually, but UDP broadcasts should fix that. But I still need a TCP channel to reliably communicate with each client for things like: Chat messages, user input etc.

Researching this topic it seems that it's possible for a server to use both protocols simultaneously - but only possible (not sensical). Nobody suggests such an approach, in fact I gather from this article that it's rather bad to use both.


Now I'm very confused as to how I should handle data in my server. Unless I've completely misunderstood something about packet loss, I want to guarantee that user input resulting in 'server-request-packets' are not lost. Every answer on SO about guaranteeing delivery with UDP say, without fail, use TCP. What's more frustrating is that every server/client program I can imagine at the very least needs some of its messages guaranteed delivered (for instance 'disconnect' messages?).

Should I use UDP, TCP, both or am I just thinking completely wrong about this?

Apollonius answered 25/10, 2015 at 14:26 Comment(1)
I'm just going to point out Kyronet github.com/EsotericSoftware/kryonet which is a library for games that uses tcp and udp, and makes it much simpler. Enet enet.bespin.org is a library to implement a layer over udp to allow you to send reliable/unreliable data at the same time with the same socket. There is also a java implementation if you look. I haven't used any of these so I can't be of any assistance with it. There's nothing wrong with either approach.Furuncle
B
16

Lets get some facts on the table:

  • UDP is not reliable. Ever.

  • Under some circumstances, UDP can be particularly lossy; e.g. if there is network congestion, rate limiting or traffic profiling, or if the UDP message size is larger than the MTU.

  • UDP broadcast only works on your local network segment. Internet routers generally don't allow broadcasts to propagate further than that. That really limits its usefulness.

  • UDP multicast might be a possibility except that that tends to be blocked too.

So this probably leaves you with two main possibilities:

  • UDP point-to-point messaging from your server to each of the clients.
  • TCP from the server to each of the clients.

Another possibility is some kind of peer-to-peer mesh communications using UDP or TCP, but that gets really complicated. Don't go there unless you really need to, and really know what you are doing.

So to your question.

Should I use UDP, TCP, both or am I just thinking completely wrong about this?

I recommend using TCP between the server and each client, because it is simplest. To simplify even further, use multiple TCP connections per client to avoid the complexity of multiplexing multiple "conversations" a single socket.

The network performance won't be optimal, but it could well be good enough your application. And I doubt that this is the part of your application where you want to be spending all your developer time.

When you get to the point of having a working application (client & server sides) and there are people using it, you may find (or not!) that the networking is a major bottleneck and cause of user dissatisfaction. Then you look at optimizing the communications in version 2.0 of your application.

When you come to implement version 2.0 (or 3.0 ...) to address scalability, you will need to move a way from dependence on a single server. Put simply, if you have N clients, and N keeps increasing, then at some point a single server won't be able to cope. Other things in the application design can be problematic too. For example, in a gaming application, you can't send continual updates about each player to all other players ... where the number of players keeps growing. But note that these issues are largely independent of the network protocols that you use.

Bianca answered 31/10, 2015 at 13:35 Comment(12)
I hadn't recognized the distinction between broadcast and multicast. The oracle trails only talks about multicast and make no such warnings.Apollonius
Here's the thing: I am able to use both TCP and UDP to write working applications. You're making the assumption that I don't want to spend my time on this, but that is exactly what I want. I want to do it 'the right way', even though I realize there is no such way. But I must insist that there is a general way to do it right. My application will never be used by more than a couple of people simultanously. But the design should be such that it could!Apollonius
When my concerns expand beyond simply establishing connections between client and server, I run into the problem as described in my answer. You seem to have thought that I assumed UDP could be reliable. Let me clarify (because a big part of my problem could be a misunderstanding there). Datagrams can be written such that they mimic the TCP protocol - with header information about what number it is, ACK etc. That's what I mean about ensuring delivery with UDP.Apollonius
Well, frankly, if you are prepared to spend time on it, then ... just do it. Try all of the alternatives, and do the scaling experiments, and that will tell you which is the best. We cannot give you detailed reliable advice about which alternatives are going to work best for you because it depends on a whole bunch of variables ...Bianca
"But I must insist that there is a general way to do it right." - Not correct. There are lots of ways that might be the best way, but it really depends on the details of the application ... and what your criteria for "best" are.Bianca
I must blindly assume that I am going completely wrong about something. Otherwise there WOULD be information I'm looking for on the internet. I don't know where I'm going wrong, though. I could just do what I want to do: use both protocols simultaneously, it would solve all my problems: and I propably wouldn't experience that I was doing it wrong.Apollonius
Yes ... your mistake is thinking that there is one true solution. The reason you can't find it using Google is ... it doesn't exist.Bianca
I am asserting that almost all server/client applications need at least some information exchanged reliably. Is this incorrect?Apollonius
For some meanings of "almost all", yes that is correct.Bianca
You say I can't send too much information too every client, of course, and that these problems are independant of what protocol is being used. But if the information I send doesn't need to be delivered (it doesn't; in the hopes that it will allow me to send more) I will be using UDP to update clients... about SOME things. Is this not correct?Apollonius
Let us continue this discussion in chat.Bianca
"To simplify even further, use multiple TCP connections per client to avoid the complexity of multiplexing multiple "conversations" a single socket." why it should be more simple? Actually is more clear and easy to mantain if you use one connection per client with a well defined protocol. However is very very inefficient he has to send many message in a second and establish every time a TCP connection could not work just because some times and in some countries astablish a connection takes half a second, this means that in some circumstances he will send only two or three messages in a secondCounterclaim
C
6

.. but UDP broadcasts should fix that

broadcast work only inside a local network and the related multicast needs support by the infrastructure - not trivial.

Apart from that: there is no general rule for "..writing a client/server application...". The communication methods and protocols depend highly on the use case and can range from simple UDP or TCP packets to sophisticated message passing architectures with reliability and real time guarantees etc.

Thus what you need to do depends on what you are trying to achieve, which you did not specify detailed enough.

Crock answered 25/10, 2015 at 15:14 Comment(6)
broadcast work only inside a local network so a server will never broadcast to clients? I will still be using UDP (for speed) to send updates to each client individually, then. So what do I do for my packages send from the client to server? (these should not be lost, should they??)Apollonius
What I'm trying to achieve is simple communication, honestly. Clients should be able to ask for data from the server, as in any trivial client/server applications. If the server fail to respond to a user input, the user shouldn't ask again because the packet might have been arbitrarily lost. The client should assume there are network problems and ask the server again (multiple requests to the server from the single user input). Just like would be the case if I had used TCP. But for updating I need UDP, no?Apollonius
@user2651804: Just to correct some of your assumptions: UDP and TCP are just transport methods and you can use both in either direction (i.e. use of TCP for updates is possible). UDP is not necessarily faster, but the latency can be lower at the cost of reliability. I recommend to look at existing client/server scenarios like HTTP, which only uses TCP.Crock
The question may sound stupid, but how do I 'look' at it? I think you are correct that I am making many false assumptions.. But I don't know where to look for more accurate information. But HTTP is one-time transfer of a file, correct? It has no use for UDP. Can you correct my assumption that most server/client applications will require TCP(or some other way to guarantee messages are delivered) and that simultaneously, but contradictingly, some of these will benefit from self contained messages (UDP), and therefore use them, too?Apollonius
@user2651804: HTTP is a request/response protocol and can have multiple requests/response in a single TCP connection. SMTP (Mail), FTP, IMAP,... all use TCP only. UDP is mostly used by real-time application like RTP, RTSP (real-time audio/video) etc and only because in these cases a short latency is required and packet loss accepted. In some cases both UDP and TCP can be used (DNS, SIP) depending on the exact use case. Again, it is all a question of use the use case and most client/server applications use TCP because most use cases includes the reliability requirement.Crock
@user2651804: I would recommend that you make an initial design of your application independent from the question if UDP or TCP is better, but just model the communications. And then you can decide later which communications are done by UDP and which are done by TCP based on the advantages and disadvantages of each of this protocols.Crock
C
1

Forget about broadcast protocols, they just don't work as somebody has already written. You need to deliver your message to every single client, make a class StateChangeDispatcher or something like that.

UDP is not reliable but is faster than TCP expecially considering that there's no handshake. Handshake is not only slow but also a little bandwidth consuming expecially when you have to establish a connection with a lot of clients.

Using both UDP and TCP isn't that bad, a lot of famous program adopt this approach. For example BitTorrent can use both protocols: UDP for communicating with tracker and to manage the DHT and TCP to transfer chunk of files. That's my explanation about their choice: the tracker or the DHT is interrogated periodically, that means that in one day of usage you could update your tracker hundreds of times, if some times that didn't work isn't a big deal because you are updating you tracker next time anyways(the same idea is in the DNS protocol, you send your request via UDP, if you don't receive a response in a reasonable amount of time you just resend the request). The TCP protocol instead MUST be used for file transfer because you prefer to be more slow but you want absolute reliability.

Another famous application that uses both protocols is Skype but for different reasons. The videocalls are UDP, that's because TCP protocol when receive a wrong packet stops and request the packet again, this requires time. So is preferable to not stop the call but receive and process a wrong packet. That's why in skype you sometimes receive a bad video or an incomprehensible audio, you could receive the video as it is recorder but it wuold be too slow. TCP is used for other things like sending files.

So you have to send messages to a lot of clients many times a second. I would't establish a new TCP connection every message. In my opinion you have this two options:

  1. send every server's state change via UDP if and only if you can afford some data loss
  2. Establish one TCP connection for each client and with that connection send all the server's state change, than close the connection when the client disconnects

A famous protocol that uses two TCP connection is FTP, you have one connection to send orders and receive responses to the server and one connection to send and receive files, recall that you don't establish a connection every command even if the commands can be sended very spaced in time (surely more than many times in a second) to avoid too much handshakes. You have a lot of patterns you can follow but mind that testing protocols is expensive (you need a lot of time and you may need more than 10 computers to see if everything works) so think well before start coding, in internet you can find some mathematical methods to calculate your protocol performance and bandwidth usage but they aren't very simple. Good luck.

Counterclaim answered 7/11, 2015 at 11:30 Comment(5)
You mention skype. TCP is used for sending files. Would it not also be used for sending messages? Or to 'start' the call, or to ask anything else of the server with user inputs? That is my confusion. While some applications obviously can benefit from UDP, what applications can possible do without TCP? You say it's not that bad to use both protocols. That probably means I shouldn't do it. What should I do? I benefit from UDP. If the clients aren't updated, they will be the next time anyway - as you say. But obviously there needs to be TCP. When the client tries to update the server state.Apollonius
Actually, can you mention an application that uses ONLY UDP, then we can narrow down the problem from there.Apollonius
I already mentioned it, the DNS protocol uses only udp and it's a protocol in the application layer , but i understand that is a very particuar case. Of course if you can't afford data loss you have to use TCP , my point is that it's not a bad practice using both protocols (and it's not more difficult or expensive). You just have to figure out if you can admit data loss and where you can admit that. user2651804 made an interesting comment that i totally agree with on the answer aboveCounterclaim
'if I can't afford data loss, I have to use TCP'. Well, do you mean to say that data is being lost in the DNS protocol? To avoid missunderstanding, I'll just explain my conception of DNS protocol: I ask my browser to locate a web server. Period. So you say I ask using UDP. But I claim that if I have internet connection, and the web server is online and capable of handling the request - I will get a response. That's what I call 'reliable communication' in my question. User input will not be lost. It seems to me, then, that DNS protocol uses UDP to achieve what TCP does. (Resend packets).Apollonius
As every answer in this thread says: #15629829 use TCP. Not UDP.Apollonius
C
0

Same principe as You are asking is used in DNS servers. The DNS is normally using UDP to transfer QUICKLY (principe of UDP protocol), but not reliably. TCP is slower (with ACKs and payload), but reliable. So as I rite below, use both, distinguish by payload.

From DNS BIND documentation:

Normally, ordinary queries use UDP, and zone transfers use TCP.

However, DNS limits UDP queries and responses to about 500 bytes. If a response would be larger than that, the server sends back up to 500 bytes and sets the "truncated" flag. The client is then supposed to perform the same query again using TCP, which is almost unlimited in the size of response it can send...

If you wan to update ALL servers in one time, register them to the MULTICAST and by one process you communicate with all of you client servers. It is again unreliable, but fast. https://en.wikipedia.org/wiki/IP_multicast So, you create server, to which the multicast partners will be registered and listen from it. To be sure you detect that UDP datagrams are dropping on the route each UD datagram has his ID number. Be sure you can also receive datagrams in different order in which you send them, so BUFFER or QUEUE should be used, calculating the right order.

Hope that helps.

Clemmieclemmons answered 7/11, 2015 at 8:17 Comment(0)
S
0

If it's a Client/Server Game like Action Game, I recommend you TCP for the UI , you DONT want to loose the users Data, but In-Game you can't afford the communication in TCP in fast action multiplayer game.

Because loosing "some" informations is not that bad in an Action game so I would recommend UDP in-game, or wherever you need VERY fast communication.

But if it's not a game who needs fast communication, I would recommend you TCP.

Selima answered 7/11, 2015 at 11:47 Comment(1)
I agree. In an action game it may be useful to use UDP. And the user input may not be lost. And so I could just go right ahead and use both protocols. Which seems obvious to me. People discourage this in general.Apollonius
C
0

It seems to me you are thinking of reliable method for Client/Server communication, which will be like Broadcast without the overhead TCP/IP communication has.

I can also adwise you to use Messaging. Create message-drive bean (or message client, concumer) which will be registered to a message channel or message queue and will activate upon the PUSH method.

Your message producer creates one message and all the other registered client servers (consumers) will be informed about it and will process it asynchronously. You can use any platform, and also open source apache MQ. https://en.wikipedia.org/wiki/Message_queue

Clemmieclemmons answered 7/11, 2015 at 12:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.