Reputation: 1614
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?
Upvotes: 12
Views: 3462
Reputation: 719476
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:
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.
Upvotes: 16
Reputation: 71
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
Upvotes: 0
Reputation: 451
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.
Upvotes: 0
Reputation: 466
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:
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.
Upvotes: 1
Reputation: 71
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.
Upvotes: 0
Reputation: 123551
.. 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.
Upvotes: 6