Hot questions for Using Transmission Control Protocol in udp

Question:

I have a REST endpoint and I want to access it using UDP for example Java Datagram. I know its not a best practice to try even but my recent project I have some hardware limitations. Hardware can make UDP calls only and my existing services are over REST i.e. HTTP/HTTPS. I am looking for any way I can reuse my existing services. I have tried following code but received UnknownHostException.

public class UDPClinet {
    public static void main(String[] args) {
        String hostname = "https://jsonplaceholder.typicode.com/posts/1";
        int port = 80;
        try {
            InetAddress address = InetAddress.getByName(hostname);
            DatagramSocket socket = new DatagramSocket();
            while (true) {
                DatagramPacket request = new DatagramPacket(new byte[1], 1, address, port);
                socket.send(request);
                byte[] buffer = new byte[512];
                DatagramPacket response = new DatagramPacket(buffer, buffer.length);
                socket.receive(response);
                String quote = new String(buffer, 0, response.getLength());
                System.out.println(quote);
                System.out.println();
                Thread.sleep(10000);
            }
        } catch (SocketTimeoutException ex) {
            System.out.println("Timeout error: " + ex.getMessage());
            ex.printStackTrace();
        } catch (IOException ex) {
            System.out.println("Client error: " + ex.getMessage());
            ex.printStackTrace();
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }
}

Answer:

Is it possible to implement a RESTful service that can be called via UDP.

Yes. (See below)

Can you call your existing RESTful service via UDP?

Almost certainly no.


Typical RESTful services are in fact implemented using HTTP or HTTPS over TCP/IP connections. It is not impossible to talk directly to an TCP-based service using UDP. The IP-level packets will have the wrong protocol family and the service's OS won't route them to the service.

In fact, it is possible (technically speaking) to implement RESTful services over any transport that is capable of sending messages. REST principles are agnostic of the transport protocol.

The problem is finding a service framework that will support this, and also conventional RESTful HTTP.

There are a couple of other practical problems:

  • UDP is unreliable, and this is exacerbated if you send datagrams that won't fit into a packet with the default MTU (1500 bytes).

  • HTTPS uses TLS so that the client to validate the server's authenticity and then send data encrypted. TLS over UDP is possible (it is called DTLS) and supported by JCSE, but using it in a typical RESTful / HTTP framework may be challenging.

If you want to pursue this, look for a RESTful framework that implements CoAP (Constrained Application Protocol - RFC 7252) and DTLS.

Question:

Sorry for such the long post. I have done lots and lots of research on this topic and keep second guessing myself on which path I should take. Thank you ahead of time for your thoughts and input.

Scenario:

Create a program in Java that sends packets of data every .2-.5 seconds that contain simple "at that moment" or live data to approximately 5-7 clients. (Approximately only 10 bytes of data max per packet). The server can be connected via wifi or ethernet. The clients however are restricted to only using Wifi. The client(s) will not be sending any packets to the server as it will only display the data retrieved from the server.


My Thoughts:

I originally started out creating the server program using TCP as the transport layer. This would use the ServerSocket class within Java. I also made it multithreaded to accept multiple clients.

TCP sounded like a great idea for various reasons.

  1. With TCP, the message will always get sent unless the connection fails.
  2. TCP rearranges the order of packets sent.
  3. TCP has flow control and requires more time to set up when started.

So, perfect! The flow control is crucial for this scenario (since the client wants the most concurrent information), the setup time isn't that big of a deal, and I am pretty much guaranteed that the message will be received. So, its official, I have made my decision to go with TCP....

Except, what happens when TCP gets behind due to packet loss? "The biggest problem with TCP in this scenario is its congestion control algorithm, which treats packet loss as a sign of bandwidth limitations and automatically throttles the sending of packets. On 3G or Wi-Fi networks, this can cause a significant latency."

After seeing the prominent phrase "significant latency", I realized that it would not be good for this scenario since the client needs to see the live data at that moment, not continue receiving data from .8 seconds ago. So, I went back to the drawing board.

After doing more research, I discovered another procedure that involved UDP with Multicasting. This uses a DatagramSocket on the server side and a MulticastSocket on the client side.

UDP with Multicasting also has its advantages:

  1. UDP is connectionless, meaning that the packets are broadcasted to anyone who is listening.
  2. UDP is fast and is great for audio/video (although mine is simple data like a string).
  3. UDP doesn't guarantee delivery - this can be good or bad. It will not get behind and create latency, but there is no guarantee that all client(s) might receive the data at that moment.
  4. Sends one packet that gets passed along.

Since the rate of sending the packets will be rather quick (.2-.5 sec), I am not too concerned about losing packets (unless it is consistently dropping packets and looks to be unresponsive). The main concern I have with UDP above anything is that it doesn't know the order of which the packets were sent. So, for example, lets say I wanted to send live data of the current time. The server sends packets which contain "11:59:03", "11:59:06", "11:59:08", etc. I would not want the data to be presented to the client as "11:59:08", "11:59:03", "11:59:06", etc.


After being presented with all of the information above, here are my questions:

  • Does TCP "catch up" with itself when having latency issues or does it always stay behind once the latency occurs when receiving packets? If so, is it rather quick to retrieving "live" data again?

  • How often do the packets of data get out of order with UDP?

And above all:

  • In your opinion, which one do you think would work best with this scenario?

Thanks for all of the help!


Answer:

Does TCP "catch up" with itself when having latency issues or does it always stay behind once the latency occurs when receiving packets?

TCP backs its transmission speed off when it encounters congestion, and attempts to recover by increasing it.

If so, is it rather quick to retrieving "live" data again?

I don't know what that sentence means, but normally the full speed is eventually restored.

How often do the packets of data get out of order with UDP?

It depends entirely on the intervening network. There is no single answer to that.

NB That's a pretty ordinary link you're citing.

  • UDP stands for 'User Datagram Protocol', not 'Universal Datagram Protocol'.
  • UDP packets do have an inherent send order, but it isn't guaranteed on receive.
  • 'UDP is faster because there is no error-checking for packets' is meaningless. 'Error-checking for packets' implies retransmission, but that only comes into play when there has been packet loss. Comparing lossy UDP speed to lossless TCP speed is meaningless.
  • 'UDP does error checking' is inconsistent with 'UDP is faster because there is no error-checking for packets'.
  • 'TCP requires three packets to set up a socket connection, before any user data can be sent' and 'Once the connection is established data transfer can begin' are incorrect. The client can transmit data along with the third handshake message.
  • The list of TCP header fields is incomplete and the order is incorrect.
  • For TCP, 'message is transmitted to segment boundaries' is meaningless, as there are no messages.
  • 'The connection is terminated by closing of all established virtual circuits' is incorrect. There are no virtual circuits. It's a packet-switching network.
  • Under 'handshake', and several other places, he fails to mention the TCP four-way close protocol.
  • The sentences 'Unlike TCP, UDP is compatible with packet broadcasts (sending to all on local network) and multicasting (send to all subscribers)' and 'UDP is compatible with packet broadcast' are meaningless (and incidentally lifted from an earlier version of a Wikipedia article). The correct term here is not 'compatible' but supports.

I'm not fond of this practice of citing arbitrary Internet rubbish here and then asking questions based on it.

Question:

I am making a real-time java game for my friends to play on LAN. The game is working in a client-server architecture, and it is using UDP for everything right now (for both position updates and joining to the game). When I tested the game with my friend over the Internet, a few important UDP packets were lost (like the one that is for spawning enemy).

So my question is, what is the best solution for making real-time multiplayer games, work? Can I use UDP for the necesarry update packets and TCP for packets like log-in, disconnect, chat etc. ? Can i use both protocol on the same port and socket?


Answer:

you can combine both.Sometimes you may want reliable data ,that time you need TCp.Sometimes its not required so that time u can use UDP.Combine the both.

Question:

I have the following files:

https://gist.github.com/anonymous/58c7cf4341acfe83f279

I am aware I can greatly simplify this, I am simply doing this for conceptual reasons.

When I run this, only the UDP connection works. When I comment out the UDP, the TCP works fine.

Why are both sockets not working at the same time? I feel like it's something to do with threading but if I understand correctly they are both using different thread pools so I am completely at a loss.

All I want to do currently is have something to listen/write to one socket for TCP, and one socket for UDP. (Possibly have a UDP write as a 3rd socket).

Any advice?


Answer:

Your servers are executed in a sequential way. Only when your UDP server is closed, then your TCP is executed.

One solution is to modify the UDP server to avoid blocking at the end. Change:

  b.bind(port).sync().channel().closeFuture().await();

to:

  b.bind(port);

And drop the group.shutdownGracefully() in the finally (you will have to do at another place anyway.)

Another (maybe better) way: The code could be adapted to be executed in two threads in order to allow concurrent execution. Add "implmement Runnable" to your UdpServer and TcpServer, and drop the throws Exception by catching it. Next run two threads from main:

new Thread(new UdpServer(9094)).start();
new Thread(new TcpServer(9093)).start();

Question:

We are working on a Android project with the below requirements.

  • The application should be able to send data to all the devices which are running our application which exists in the WiFi LAN.
  • Some payloads are expected to be of size >= 5MB.
  • The data shouldn't be lost and if lost the client should know the failure.
  • All the devices should be able to communicate with all other. There will be no message targeted to a specific device instead all the messages should be reached all the devices in the N/W.
  • No internet hence no remote server.

Study we have done:-

  • UDP Broadcasting - UDP doesn't guarantee the message delivery but this is a prime requirement in our case. Hence not an option.

  • TCP - TCP guarantees the message delivery but requires the receiver IP address to be known before hand and in our case we need to send the message to all the devices inside the LAN. Hence not a straight option.

Solutions we are looking into:-

  • A Hybrid approach - Name one of the devices in the N/W as Server. Post all the messages to a local Server. The Server keeps a open socket to all the devices(which have our application) & when there is a message from a device then it routes the message to all the devices. The disadvantages of this approach are,

    • Server having multiple sockets open each per device. But in our case we are expecting devices <=5 in LAN.
    • Server discovery using continuous UDP broadcast.
    • We want to have all the data in all the devices. So if we newly introduce any device into the LAN then that device needs to get all the data from the server.

So my question, have you any time worked on these kind of hybrid approaches? Or can you suggest any other approaches?


Answer:

Your hybrid approach is the way to go.

Cleanly split your problem into parts and solve them independently:

  • Discovery: Devices need to be able to discover the server, if there is any.
  • Select server: Decide which of your devices assumes the server role.
  • Server implementation: The server distributes all data to all devices and sends notifications as necessary. Push or pull with notifications does not matter.
  • Client implementation: Clients only talk to the server. The device which contains the server should also contain a normal client, potentially passing data to the server directly, but using the same abstract protocol.

You could use mDNS (aka Bonjour or zeroconf) for the discovery, but I would not even recommend that. It often createsmore problems than it solves, and it does not solve your 'I need one server' problem. I would suggest you handcraft a simple UDP broadcast protocol for the discovery, which already tells you who the server is, if there is any.

Select server: One approach is to use network meta data which you have anyway, for example 'use the device with the highest IP address'. This often works better than fancy arbitration algorithms. Once you established a server new devices would use this, rather than switching the server role.

Use UDP broadcast for the discovery, with manual heuristic repeats. No fancy logic, just make your protocol resilient against repeated packets and repeat your packets. (Your WLAN router may repeat your packets without your knowledge anyway.)

You may want to use two TCP connections per client, potentially to two different server ports, but that does not matter much: One control connection (always very responsive, no big amounts of data, just a few hundred bytes per message) and one data connection (for the bulk of the data, your > 5 MB chunks). This is so that everything stays responsive.

Question:

I try to develop simple mmorpg.Since there are 2 priorities of data to be sent, one is the TCP based information that must be sent from the server and the other is UDP based as character movement is there a way to setup UDP protocol to be able to work also as TCP depending of package priority?So there would be no need to open 2 connections from server to the client.


Answer:

You seem to be asking if it is possible to replace a TCP bytestream and a UDP "stream" of messages with something implemented just using UDP.

The answer is: "Yes in theory, but in practice it would be a lot of work, would perform poorly, and would achieve very little".

TCP is a reliable byte stream protocol that is implemented on top of an unreliable IP packet layer by keeping track of what has been sent and what has been acknowledged. If specific packets get lost / dropped by the network, the sender or receiver notice and the missing data gets retransmitted. TCP also implements flow control so that the protocol does not overload the network.

By contrast, UDP does not provide either reliability or flow control.

It would be possible to implement TCP-like reliability and flow control over any unreliable packet layer ... including UDP/IP. However, to do this in Java, you would need to implement a TCP-like protocol in a "user-space" application library on both the client and server sides. That is a lot of work, and the performance would inevitably be inferior to a real TCP/IP implementation in the OS kernel.

Besides, while you are eliminating TCP/IP sockets, you are replacing them with equivalent data structures and buffering in the Java application itself. In practice, this is unlikely to save resources on either server or client side.