I keep hearing people say, to get a better throughput you create multiple socket connection.
But my understanding is that however many tcp sockets you open between two end points. the ip layer is still one. So not sure where this additional throughput comes from
The additional throughput comes from increasing the amount of data sent in the first couple of round trip times (RTTs). TCP can send only IW packets the first round trip time (RTT). The amount is then doubled each RTT (slow start). If you open 4 connections you can send 4 * IW packets the first RTT. The throughput is quadrupled.
Lets say that a client requests a file that requires IW+1 packets. Opening two connections can complete the sending in one RTT, rather than two RTTS.
HOWEVER, this comes at a price. The initial packets are sent as a burst, which can cause severe congestion and packet loss.
Related
I am willing to know about the comparison of the Packet delivery rate between MQTT and CoAP transmission. I know that TCP is more secure than UDP, so MQTT should have a higher Packet delivery rate. I just want to know, if 2000 packets are sent using both protocols separately what would be the approximate percentage in the two cases?
Please help with an example if possible.
If you dig a little, you will find, that both, TCP and UDP, are mainly sending IP messages. And some of these messages may be lost. For TCP, the retransmission is handled by the TCP protocol without your influence. That sure works not too bad (at least in many cases). For CoAP, when you use CON messages, CoAP does the retransmission for you, so also not too much to lose.
When it comes to transmissions with more message loss (eg. bad connectivity), the reliability may also depend on the amount of data. If it fits into one IP message, the probability that this reaches the destination is higher, than 4 messages reaching their destination. In that situation the difference starts:
Using TCP requires, that all the messages are reaching the destination without gaps (e.g. 1,2, (drop 3), 4 will not work). CoAP will deliver the messages also with gaps. It depends on your application, if you can benefit from that or not.
I've been testing CoAP over DTLS 1.2 (Connection ID) for mostly a year now using a Android phone and just moving around sending request (about 400 bytes) with wifi and mobile network. It works very reliable. Current statistic: 2000 request, 143 retransmissions, 4 lost. Please note: 4 lost mainly means "no connection", so be sure, using TCP will have results below that, especially when moving around and frequently new TCP/TLS handshakes get required.
So my conclusion:
If you have a stable network connection, both should work.
If you have a less stable network connection and gaps are not acceptable by your application, both have trouble.
If you have a less stable network connection and gaps are acceptable by your application, then CoAP will do a better job.
I know, I know. This question has been asked many times before. But I've spent an hour googling now without finding what I am looking for so I will ask it again and mention my context along with what makes the decision hard for me:
I am writing the server for a game where the response time is very important and a packet loss every now and then isn't a problem.
Judging by this and the fact that I as a server mostly have to send the same data to many different clients, the obvious answer would be UDP.
I had already started writing the code when I came across this:
In some applications TCP is faster (better throughput) than UDP.
This is the case when doing lots of small writes relative to the MTU size. For example, I read an experiment in which a stream of 300 byte packets was being sent over Ethernet (1500 byte MTU) and TCP was 50% faster than UDP.
In my case the information units I'm sending are <100 bytes, which means each one fits into a single UDP packet (which is quite pleasant for me because I don't have to deal with the fragmentation) and UDP seems much easier to implement for my purpose because I don't have to deal with a huge amount of single connections, but my top priority is to minimize the time between
client sends something to server
and
client receives response from server
So I am willing to pick TCP if that's the faster way.
Unfortunately I couldn't find more information about the above quoted case, which is why I am asking: Which protocol will be faster in my case?
UDP is still going to be better for your use case.
The main problem with TCP and games is what happens when a packet is dropped. In UDP, that's the end of the story; the packet is dropped and life continues exactly as before with the next packet. With TCP, data transfer across the TCP stream will stop until the dropped packet is successfully retransmitted, which means that not only will the receiver not receive the dropped packet on time, but subsequent packets will be delayed also -- most likely they will all be received in a burst immediately after the resend of the dropped packet is completed.
Another feature of TCP that might work against you is its automatic bandwidth control -- i.e. TCP will interpret dropped packets as an indication of network congestion, and will dial back its transmission rate in response; potentially to the point of dialing it down to near zero, in cases where lots of packets are being lost. That might be useful if the cause really was network congestion, but dropped packets can also happen due to transient network errors (e.g. user pulled out his Ethernet cable for a couple of seconds), and you might not want to handle those problems that way; but with TCP you have no choice.
One downside of UDP is that it often takes special handling to get incoming UDP packets through the user's firewall, as firewalls are often configured to block incoming UDP packets by default. For an action game it's probably worth dealing with that issue, though.
Note that it's not a strict either/or option; you can always write your game to work over both TCP and UDP, and either use them simultaneously, or let the program and/or the user decide which one to use. That way if one method isn't working well, you can simply use the other one, and it only takes twice as much effort to implement. :)
In some applications TCP is faster (better throughput) than UDP. This
is the case when doing lots of small writes relative to the MTU size.
For example, I read an experiment in which a stream of 300 byte
packets was being sent over Ethernet (1500 byte MTU) and TCP was 50%
faster than UDP.
If this turns out to be an issue for you, you can obtain the same efficiency gain in your UDP protocol by placing multiple messages together into a single larger UDP packet. i.e. instead of sending 3 100-byte packets, you'd place those 3 100-byte messages together in 1 300-byte packet. (You'd need to make sure the receiving program is able to correctly intepret this larger packet, of course). That's really all that the TCP layer is doing here, anyway; placing as much data into the outgoing packets as it has available and can fit, before sending them out.
I want to transfer a large number of messages. The messages do not need to be reliable. UDP comes to mind as a protocol choice.
Latency is important as well. I do not want to suffer from TCP head-of-line blocking.
I'm concerned I might overload the network when I just start sending messages at maximum speed (e.g. while (messagesRemaining != 0) Send(...);). If I send more than some middle-box can relay then, I think, large numbers of messages might be dropped. Some messages being dropped is fine but most of them should arrive.
How can I address this issue? How can I find out how fast I can send? I want to maintain reasonable packet loss (a few percent) and otherwise maximize bandwidth.
Whether you will overload the network or not depends on what is between the sender and the receiver hosts. The iperf utility has a UDP option that could help you determine the max rate you could send for a certain level of acceptable packet loss.
That said, from personal experience:
If it's local Gigabit network and client/server on same subnet, I highly doubt you would lose any packets. I've done tests before with iperf in this type of environment and never lost any packets; iperf is going to be one of the fastest and most efficient ways to put UDP packets on to the wire from a PC and we still never lost packets. We were even running the packets through an intel Atom-based Linux host with bridged ports setup while doing tcpdump at the same time and still never lost packets (note that even cheapo switches would perform as good or better than a bridge setup in a PC). The only way we were ever able to get packets to be lost was when we used FPGA/ASIC test devices that could put packets onto the wire at true line-speed for long periods of time. Even at that, the test setup was only losing packets when the packets were less than around 500 bytes.
If you aren't on a local network though (i.e. going over internet or routers) you will just need to do some testing with iperf to see what is acceptable for your environment. Problem is though that what rate can be sustained one day isn't guaranteed to be the same the next day. UDP doesn't have any sort of congestion/flow control algorithms like TCP does so you will have to figure out on your own how fast you can send.
I'm considering whether to use TCP or UDP for some really simple communication I'm working on. Here are the basic details:
All messages fit in a single 1500-byte packet (so ordering is irrelevant)
The recipient of these messages will be bombarded with packets from a number of different sources. TCP would handle congestion, but would UDP packets arriving at the same port simultaneously from tens or hundreds of sources corrupt each other?
Missed/corrupted messages are not a big deal. So long as they remain a small minority, and they are correctly identified as invalid, they can just be ignored
Packets arrive in waves, a few per second for a few seconds and then tens of thousands in a fraction of a second. The network should be able to handle the bandwidth in these spikes
Do you see any problem with using UDP for this, keeping in mind that ordering doesn't matter, lost/corrupted packets can be safely ignored, and these packet spikes will have tens of thousands of packets arriving possibly simultaneously?
All messages fit in a single 1500-byte packet (so ordering is irrelevant)
1500 is the MTU usually used in local networks. It can be lower on the internet and protocols like DNS assume that at least 512 byte will work. But even if the MTU is lower the packet gets only fragmented and reassembled at the end, so no half messages arrive at the application.
.. but would UDP packets arriving at the same port simultaneously from tens or hundreds of sources corrupt each other?
They would not corrupt each other. If they arrive too fast and your application is not able to read them in time from the socket buffer so that the socket buffer fills up then the packet will simply be lost.
Missed/corrupted messages are not a big deal. So long as they remain a small minority, and they are correctly identified as invalid, they can just be ignored
There is an optional checksum for UDP which gets used in most cases. If the checksum does not fit the packet gets discarded, i.e. not delivered to the application. The checksum does account for simple bitflips but will not be able to detect every corruption. But this is the same with all checksums and also with TCP.
Packets arrive in waves, a few per second for a few seconds and then tens of thousands in a fraction of a second. The network should be able to handle the bandwidth in these spikes
If the bandwidth in the network can deal with it then the network is able to handle it. But the question is if your local machine and especially your application is able to cope with such waves, that is to process packets that fast that the buffer of the network card and the socket buffer not overflow. You should probably increase the receive buffer size to better deal with such waves.
All messages fit in a single 1500-byte packet (so ordering is irrelevant)
Non sequitur. The generally accepted payload limit for UDP datagrams is 534 bytes, and the fact that all messages fit into one datagram doesn't imply that order is irrelevant, unless the order of messages is irrelevant, which you haven't stated.
would UDP packets arriving at the same port simultaneously from tens or hundreds of sources corrupt each other?
No.
Missed/corrupted messages are not a big deal. So long as they remain a small minority, and they are correctly identified as invalid, they can just be ignored.
If you don't disable UDP checksum checking, they will be dropped, not ignored.
Packets arrive in waves, a few per second for a few seconds and then tens of thousands in a fraction of a second. The network should be able to handle the bandwidth in these spikes.
It won't. UDP packets can be dropped any time, especially under conditions like these. But as you've already stated that missed messages are not a big deal, it isn't a big deal.
Do you see any problem with using UDP for this, keeping in mind that ordering doesn't matter, lost/corrupted packets can be safely ignored, and these packet spikes will have tens of thousands of packets arriving possibly simultaneously?
Not under the conditions you have stated, assuming they are correct.
I'd like to know the general cost of creating a new connection, compared to UDP. I know TCP requires an initial exchange of packets (the 3 way handshake). What would be other costs? For instance is there some sort of magic in the kernel needed for setting up buffers etc?
The reason I'm asking is I can keep an existing connection open and reuse it as needed. However if there is little overhead reconnecting it would reduce complexity.
Once a UDP packet's been dumped onto the wire, the UDP protocol stack is free to completely forget about it. With TCP, there's at bare minimum the connection details (source/dest port and source/dest IP), the sequence number, the window size for the connection etc... It's not a huge amount of data, but adds up quickly on a busy server with many connections.
And then there's the 3-way handshake as well. Some braindead (and/or malicious systems) can abuse the process (look up 'syn flood'), or just drop the connection on their end, leaving your system waiting for a response or close notice that'll never come. The plus side is that with TCP the system will do its best to make sure the packet gets where it has to. With UDP, there's no guarantees at all.
Compared to the latency of the packet exchange, all other costs such as kernel setup times are insignificant.
OPTION 1: The general cost of creating a TCP connection are:
Create socket connection
Send data
Tear down socket connection
Step 1: Requires an exchange of packets, so it's delayed by to & from network latency plus the destination server's service time. No significant CPU usage on either box is involved.
Step 2: Depends on the size of the message.
Step 3: IIRC, just sends a 'closing now' packet, w/ no wait for destination ack, so no latency involved.
OPTION 2: Costs of UDP:*
Create UDP object
Send data
Close UDP object
Step 1: Requires minimal setup, no latency worries, very fast.
Step 2: BE CAREFUL OF SIZE, there is no retransmit in UDP since it doesn't care if the packet was received by anyone or not. I've heard that the larger the message, the greater probability of data being received corrupted, and that a rule of thumb is that you'll lose a certain percentage of messages over 20 MB.
Step 3: Minimal work, minimal time.
OPTION 3: Use ZeroMQ Instead
You're comparing TCP to UDP with a goal of reducing reconnection time. THERE IS A NICE COMPROMISE: ZeroMQ sockets.
ZMQ allows you to set up a publishing socket where you don't care if anyone is listening (like UDP), and have multiple listeners on that socket. This is NOT a UDP socket - it's an alternative to both of these protocols.
See: ZeroMQ.org for details.
It's very high speed and fault tolerant, and is in increasing use in the financial industry for those reasons.