    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Once Again on TCP vs UDP</title>
        <link>https://members.accu.org/index.php/articles/2180</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + Overload Journal #130 - December 2015</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c78/">Overload</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c356/">o130</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-356/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+356/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Once Again on TCP vs UDP</h1>
<p><strong>Author:</strong>&nbsp;Martin Moene</p>
<p>
<strong>Date:</strong> 06 December 2015 09:25:17 +00:00 or Sun, 06 December 2015 09:25:17 +00:00</p>
<p><strong>Summary:</strong>&nbsp;TCP and UDP have different properties. Sergey Ignatchenko weighs up their pros and cons.</p>
<p><strong>Body:</strong>&nbsp;<p class="EditorIntro">Disclaimer: as usual, the opinions within this article are those of â€˜No Bugsâ€™ Hare, and do not necessarily coincide with the opinions of the translators and <em>Overload</em> editors; also, please keep in mind that translation difficulties from Lapine (like those described in [<a href="#[Loganberry04]">Loganberry04</a>]) might have prevented an exact translation. In addition, the translator and <em>Overload</em> expressly disclaim all responsibility from any action or inaction resulting from reading this article.</p>

<p>Discussion on the advantages of TCP vs UDP (and vice versa) has a history which is almost as long as the eternal Linux-vs-Windows debate. As I have long been a supporter of the point of view that both UDP and TCP have their own niches (see, for example, [<a href="#[NoBugs15]">NoBugs15</a>]), here are my two cents on this subject.</p>

<p>Note for those who already know the basics of IP and TCP: please skip to the â€˜Closing the Gap: Improving TCP Interactivityâ€™ section, as you still may be able to find a thing or two of interest.</p>

<h2>IP: just packets, nothing more</h2>

<p>As both TCP and UDP run over IP, letâ€™s see what the internet protocol (IP) really is. For our purposes, we can say that:</p>

<ul>
	<li>we have two hosts which need to communicate with each other</li>
	<li>each of the hosts is assigned its own IP address</li>
	<li>the internet protocol (and IP stack) provides a way to deliver data packets from host A to host B, using an IP address as an identifier</li>
</ul>

<p>In practice, of course, it is much more complicated than that (with all kinds of stuff involved in the operation of the IP, from ICMP and ARP to OSPF and BGP), but for now we can more or less safely ignore the complications as implementation details.</p>

<p>What we need to know, though, it is that IP packet looks as follows:</p>

<table class="sidebartable">
	<tr>
		<td>
			<table class="journaltable">
				<tr>
					<td>IP Header (20 to 24 bytes for IPv4)</td>
				</tr>

				<tr>
					<td>IP Payload</td>
				</tr>
			</table>
		</td>
	</tr>
</table>

<p>One very important feature of IP is that it does not guarantee packet delivery. Not at all. Any single packet can be lost, period. It means that any number of packets can also be lost.</p>

<p>IP works only statistically; this behaviour is by design; actually, it is the reason why backbone Internet routers are able to cope with enormous amounts of traffic. If there is a problem (which can range from link overload to sudden reboot), routers are allowed to drop packets.</p>

<p class="lesson">Within the IP stack, it is the job of the hosts to provide delivery guarantees. Nothing is done in this regard en route.</p>

<h2>UDP: datagrams ~= packets</h2>

<p>Next, letâ€™s discuss the simpler one of our two protocols: UDP. UDP is a very basic protocol which runs on top of IP. Actually, it is that basic, that when UDP datagrams run on top of IP packets, there is always 1-to-1 correspondence between the two, and all UDP does is add a very simple header (in addition to IP headers), the header consisting of 4 fields: source port, destination port, length, and checksum, making it 8 bytes in total.</p>

<p>So, a typical UDP packet will look as follows:</p>

<table class="sidebartable">
	<tr>
		<td>
			<table class="journaltable">
				<tr>
					<td>IP Header (20 to 24 bytes for IPv4)</td>
				</tr>

				<tr>
					<td>UDP Header (8 bytes)</td>
				</tr>

				<tr>
					<td>UDP Payload</td>
				</tr>
			</table>
		</td>
	</tr>
</table>

<p>The UDP â€˜Datagramâ€™ is pretty much the same as an IP â€˜packetâ€™, with the only difference between the two being the 8 bytes of UDP header; for the rest of the article weâ€™ll use these two terms interchangeably.</p>

<p class="lesson">As UDP datagrams simply run on top of IP packets, and IP packets can be lost, UDP datagrams can be lost too.</p>

<h2>TCP: stream != packets</h2>

<p>In contrast with UDP, TCP is a very sophisticated protocol, which does guarantee reliable delivery.</p>

<p>The only relatively simple thing about TCP is its packet:</p>

<table class="sidebartable">
	<tr>
		<td>
			<table class="journaltable">
				<tr>
					<td>IP Header (20 to 24 bytes for IPv4)</td>
				</tr>

				<tr>
					<td>TCP Header (20 to 60 bytes)</td>
				</tr>

				<tr>
					<td>TCP Payload</td>
				</tr>
			</table>
		</td>
	</tr>
</table>

<p>Usually, the size of a TCP header is around 20 bytes, but in relatively rare cases it may reach up to 60 bytes.</p>

<p>As soon as weâ€™re past the TCP packet, things become complicated. Here is an extremely brief and sketchy description of TCP working<a href="#FN01"><sup>1</sup></a>:</p>

<ul>
	<li>TCP interprets all the data to be communicated between two hosts as two streams (one stream going from host A to host B, and another going in the opposite direction)</li>

	<li>whenever the host calls the TCP function <code>send()</code>, the data is pushed into the stream</li>

	<li>the TCP stack keeps a buffer (usually 2Kâ€“16K in size) on the sending side; all the data pushed to the stream goes to this buffer. If the buffer is full, <code>send()</code> wonâ€™t return until there is enough space in the buffer<a href="#FN02"><sup>2</sup></a></li>

	<li>Data from the buffer is sent over the IP as TCP packets; each TCP packet consists of an IP packet, a TCP header, and TCP data. TCP data within a TCP packet is data from the sending TCP buffer; data is <em>not</em> removed from the TCP buffer on the sending side at the moment when TCP packet is sent (!)</li>

	<li>After the receiving side gets the TCP packet, it sends a TCP packet in the opposite direction, with a TCP header with the <code>ACK</code> bit set â€“ an indication that a certain portion of the data has been received. On receiving this <code>ACK</code> packet, the sender may remove the corresponding piece from its TCP sending buffer.<a href="#FN03"><sup>3</sup></a></li>

	<li>Data received goes to another buffer on the receiving side; again, its size is usually of the order of 2Kâ€“16K. This receiving buffer is where the data for the <code>recv()</code> function comes from.</li>

	<li>If the sending side doesnâ€™t receive an <code>ACK</code> in a predefined time â€“ it will re-send the TCP packet. This is the primary mechanism by which TCP guarantees delivery in case of the packet being lost.<a href="#FN04"><sup>4</sup></a></li>
</ul>

<p>So far so good. However, there are some further caveats. First of all, when re-sending because of no-<code>ACK</code> timeouts, these timeouts are doubled for each subsequent re-send. The first re-send is usually sent after time T1, which is double the so-called RTT (round-trip-time, which is measured by the host as a time interval between the moment when the packet was sent and another moment when the <code>ACK</code> for the packet was received); the second re-send is sent after time T2=2*T1, the third one after T3=2*T2, and so on. This feature (known as â€˜exponential back-offâ€™) is intended to avoid the Internet being congested due to too many retransmitted packets flying around, though the importance of exponential back-off in avoiding Internet congestion is currently being challenged [<a href="#[Mondal]">Mondal</a>]. Whatever the reasoning, exponential back-off is present in every TCP stack out there (at least, Iâ€™ve never heard of any TCP stacks which donâ€™t implement it), so we need to cope with it (weâ€™ll see below when and why it is important).</p>

<p>Another caveat related to interactivity is the so-called Nagle algorithm. Originally designed to avoid telnet sending 41-byte packets for each character pressed (which constitutes a 4000% overhead), it also allows the hiding of more packet-related details from a â€˜TCP as streamâ€™ perspective (and eventually became a way to allow developers to be careless and push data to the stream in as small chunks as they like, in the hope that the â€˜smart TCP stack will do all the packet assembly for usâ€™). The Nagle algorithm avoids sending a new packet as long as there is (a) an unacknowledged outstanding packet and (b) there isnâ€™t enough data in the buffer to fill the whole packet. As we will see below, it has significant implications on interactivity (but, fortunately for interactivity, usually Nagle can be disabled).</p>

<h2>TCP: Just the ticket? No so fast :-(</h2>

<p>Some people may ask: if TCP is so much more sophisticated and more importantly, provides reliable data delivery, why not just use TCP for every network transfer under the sun? </p>

<p>Unfortunately, it is not that simple. Reliable delivery in TCP does have a price tag attached, and this price is all about loss of interactivity :-(.</p>

<p>Letâ€™s imagine a first-person shooter game that sends updates, with each update containing only the position of the player. Letâ€™s consider two implementations: Implementation U which sends the player position over UDP (a single UDP packet every 10ms, as the game is fast and the position is likely to change during this time anyway), and Implementation T which sends the player position over TCP.</p>

<p>First of all, with Implementation T, if your application is calling <code>send()</code> every 10 ms, but RTT is, say, 50ms, your data updates will be delayed (according to the Nagle algorithm, see above). Fortunately, the Nagle algorithm can be disabled using the <code>TCP_NODELAY</code> option (see the section â€˜Closing the gap: improving TCP interactivityâ€™ for details).</p>

 <p>If the Nagle algorithm is disabled, <em>and</em> there are no packets lost on the way (and both hosts are fast enough to process the data) â€“ there wonâ€™t be any difference between these implementations. But what will happen if some packets <em>are</em> lost? </p>

<p>With Implementation U, even if a packet is lost, the next packet will heal the situation, and the correct player position will be restored very quickly (at most in 10 ms). With Implementation T, however, we cannot control timeouts, so the packet wonâ€™t be re-sent until around 2*RTT; as RTT can easily reach 50ms even for a first-person shooter (and is at least 100â€“150ms across the Atlantic), the retransmit wonâ€™t happen until about 100ms, which represents a Big Degradation compared to Implementation U.</p>

<p>In addition, with Implementation T, if one packet is lost but the second one is delivered, this second packet (while present on the receiving host) wonâ€™t be delivered to the application until the second instance of the first packet (i.e. the first packet retransmitted on timeout) is received; this is an inevitable consequence of treating all the data as a stream (you cannot deliver the latter portion of the stream until the former one is delivered).</p>

<p>To make things even worse for Implementation T, if there is more than one packet lost in a row, then the second retransmit with Implementation T wonâ€™t come until about 200ms (assuming 50ms RTT), and so on. This, in turn, often leads to existing TCP connections being â€˜stuckâ€™ when new TCP connections will succeed and will work correctly. This can be addressed, but requires some effort (see â€˜Closing the gap: improving TCP interactivityâ€™ section below).</p>

<h2>So, should we always go with UDP?</h2>

<p>In Implementation U described above, UDP worked pretty well, but this was closely related to the specifics of the messages exchanged. In particular, we assumed that <em>every packet has all the information necessary</em>, so loss of any packet will be â€˜healedâ€™ by the next packet. If such an assumption doesnâ€™t hold, using UDP becomes non-trivial.</p>

<p>Also, the whole schema relies on us sending packets every 10ms; this may easily result in sending too much traffic even if there is little activity; on the other hand, increasing this interval with Implementation U will lead to loss of interactivity.</p>


<h2>What should we do then?</h2>

<p>Basically, the rules of thumb are about the following:</p>

<ul>
	<li>If characteristic times for your application are of the order of many hours (for example, youâ€™re dealing with lengthy file transfers) â€“ TCP will do just fine, though it is still advisable to use TCP built-in keep-alives (see below).</li>

	<li>If characteristic times for your application are below â€˜many hoursâ€™ but are over 5 seconds â€“ it is more or less safe to go with TCP. However, to ensure interactivity consider implementing your â€˜Own Keep-Alivesâ€™ as described below.</li>

	<li>If characteristic times for your application are (very roughly) between 100ms and 5 seconds â€“ this is pretty much a grey area. The answer to â€˜which protocol to useâ€™ question will depend on many factors, from â€œHow well you can deal with lost packets on application levelâ€ to â€œDo you need security?â€. See both â€˜Closing the gap: reliable UDPâ€™ and â€˜Closing the gap: improving TCP Interactivityâ€™ sections below.</li>

	<li>If characteristic times for your application are below 100ms â€“ it is very likely that you need UDP. See the â€˜Closing the gap: reliable UDPâ€™ section below on the ways of adding reliability to UDP. </li>
</ul>

<h2>Closing the gap: reliable UDP</h2>

<p>In cases when you need to use UDP but also need to make it reliable, you can use one of the â€˜reliable UDPâ€™ libraries [<a href="#[Enet]">Enet</a>] [<a href="#[UDT]">UDT</a>] [<a href="#[RakNet]">RakNet</a>]. However, these libraries cannot do any magic, so theyâ€™re essentially restricted to retransmits at some timeouts. Therefore, before using such a library, you will still need to understand very well <em>how exactly</em> it achieves reliable delivery, and how much interactivity it sacrifices in the process (and for what kind of messages).</p>

<p>It should be noted that when implementing reliable UDP, the more TCP features you implement, the more chances there are that you end up with an inferior implementation of TCP. TCP is a very complex protocol (and most of its complexity is there for a good reason), so attempting to implement â€˜better TCPâ€™ is extremely difficult. On the other hand, implementing â€˜reliable UDPâ€™ at the cost of dropping most of TCP functionality, is possible.</p>

<h2>Closing the gap: improving TCP interactivity</h2>

<p>There are several things which can be done to improve interactivity of TCP. </p>

<h3>Keep-alives and â€˜stuckâ€™ connections</h3>

<p>One of the most annoying problems when using TCP for interactive communication is â€˜stuckâ€™ TCP connections. When you see a browser page which â€˜stuckâ€™ in the middle, then press â€˜Refreshâ€™ â€“ and bingo! - here is your page, then chances are you have run into such a â€˜stuckâ€™ TCP connection. </p>

<p>One way to deal with â€˜stuckâ€™ TCP connections (and without your customer working as a freebie error handler) is to have some kind of â€˜keep aliveâ€™ messages which the parties exchange every <em>N</em> seconds; if there are no messages on one of the sides for, say, 2*<em>N</em> time â€“ you can assume that TCP connection is â€˜stuckâ€™, and try to re-establish it. </p>

<p>TCP itself includes a Keep-Alive mechanism (look for <code>SO_KEEPALIVE</code> option for <code>setsockopt()</code>), but it is usually of the order of 2 hours (and worse, at least under Windows it is not configurable other than via a global setting in the Registry, ouch). </p>

<p>So, if you need to detect your â€˜stuckâ€™ TCP connection earlier than in two hours, and your operating systems <em>on both sides of your TCP connection</em> donâ€™t support per-socket keep alive timeouts, you need to create your own keep-alive over TCP, with the timeouts you need. It is usually not rocket science, but is quite a bit of work. </p>

<p>The basic way of implementing your own keep-alive usually goes as follows:</p>

<ul>
	<li>Youâ€™re splitting your TCP stream into messages (which is usually a good idea anyway); each message contains its type, size, and payload</li>

	<li>One message type is <code>MY_DATA</code>, with a real payload. On receiving it, it is passed to the upper layer. Optionally, you may also reset a â€˜connection is deadâ€™ timer.</li>

	<li>Another message type is <code>MY_KEEPALIVE</code>, without any payload. On receiving it, it is not passed to the upper layer, but a â€˜connection is deadâ€™ timer is reset.</li>

	<li><code>MY_KEEPALIVE</code> is sent whenever there are no other messages going over the TCP connection for <em>N</em> seconds</li>

	<li>When a â€˜connection is deadâ€™ timer expires, the connection is declared dead and is re-established. While this is a fallacy from traditional TCP point of view, it has been observed to help interactivity in a significant manner.
		<p>As an optimization, you may want to keep the original connection alive while youâ€™re establishing a new one; if the old connection receives something while youâ€™re establishing the new one, you can resume communication over the old one, dropping new one.</p>
	</li>
</ul>

<h3>TCP_NODELAY</h3>

<p>One of the most popular ways to improve TCP interactivity is enabling <code>TCP_NODELAY</code> over your TCP socket (again, as a parameter of <code>setsockopt()</code> function). </p>

<p>If <code>TCP_NODELAY</code> is enabled, then the Nagle algorithm is disabled (usually <code>TCP_NODELAY</code> also has some other effects such as adding a PSH flag, which causes the TCP stack on the receiving side to deliver the data to the application right away without waiting for â€˜enough data to be gatheredâ€™, which is also a Good Thing interactivity-wise. Still, it cannot force packet data to be delivered until previous-within-the-stream packet is delivered, as stream coherency needs to be preserved).</p>

<p>However, <code>TCP_NODELAY</code> is not without its own caveats. Most importantly, with <code>TCP_NODELAY</code> you should always assemble the whole update <em>before</em> calling <code>send()</code>. Otherwise, each of your calls to <code>send()</code> will cause the TCP stack to send a packet (with the associated 40â€“84 bytes overhead, ouch).</p>

<h3>Out-of-Band Data</h3>

<p>TCP OOB (Out-of-Band Data) is a mechanism which is intended to break the stream and deliver some data with a higher priority. As OOB adds priority (in a sense that it bypasses both the TCP sending buffer and TCP receiving buffer), it may help to deal with interactivity. However, with TCP OOB being able to send only one byte (while you can call <code>send(...,MSG_OOB)</code> with more than one byte, only the last byte of the block will be interpreted as OOB), its usefulness is usually quite limited.</p>

<p>One scenario when <code>MSG_OOB</code> works pretty well (and which is used in protocols such as FTP), is to send an â€˜abortâ€™ command during a long file transfer; on receiving OOB â€˜abortâ€™, the receiving side simply reads all the data from the stream, discarding it without processing, until the OOB marker (the place in the TCP stream where <code>send(...,MSG_OOB)</code> has been called on sending side) is reached. This way, all the TCP buffers are effectively discarded, and the communication can be resumed without dropping the TCP connection and re-establishing a new one. For more details on <code>MSG_OOB</code> see [<a href="#[Stevens]">Stevens</a>] (with a relevant chapter available on [<a href="#[Masterraghu]">Masterraghu</a>]).</p>

<h3>Residual issues</h3>

<p>Even with all the tricks above, TCP is still lacking interactivity-wise. In particular, out-of-order data delivery of over-1-byte-size is still not an option, stale-and-not-necessary-anymore data will still be retransmitted even if theyâ€™re not necessary, and dealing with â€˜stuckâ€™ connections is just a way to mitigate the problem rather than to address it. On the other hand, if your application is relatively tolerant to delays, â€˜other considerationsâ€™ described below may easily be a deciding factor in your choice of  protocol.</p>

<h2>Other considerations</h2>

<p>If youâ€™re lucky enough and the requirements of your application can be satisfied by both TCP and UDP, other considerations may come into play. These considerations include (but are not limited to):</p>

<ul>
	<li>TCP guarantees correct ordering of packets, UDP as such doesnâ€™t (though â€˜Reliable UDPâ€™ might).</li>

	<li>TCP has flow control, UDP as such doesnâ€™t.</li>

	<li>TCP is generally more firewall- and NAT-friendly. Which can be roughly translated as â€˜if you want your user to be able to connect from a hotel room, or from work â€“ TCP usually tends to work better, especially if going over port 80, or over port 443â€™.</li>

	<li>TCP is significantly simpler to program for. While TCP is not without caveats, not discussed here (see also [<a href="#[NoBugs15a]">Nobugs15a</a>]), dealing with UDP so it works without major problems generally takes significantly longer.</li>

	<li>TCP generally has more overhead, especially during connection setup and connection termination. The overall difference in traffic will usually be small, but this might still be a valid concern.</li>
</ul>

<h2>Conclusions</h2>

<p>The choice of TCP over UDP (or vice versa) might not always be obvious. In a sense, replacing TCP with UDP is trading off reliability for interactivity.</p>

<p>The most critical factor in selection of one over another one is usually related to acceptable delays; TCP is usually optimal for over-several-seconds times, and UDP for under-0.1-second times, with anything in between being a â€˜grey areaâ€™. On the other hand, other considerations (partially described above) may play their own role, especially within the â€˜grey areaâ€™.</p>

<p>Also, there are ways to improve TCP interactivity as well as UDP reliability (both briefly described above); this often allows to close the gap between the two.</p>

<p><img src="http://accu.org/content/images/journals/ol130/Ignatchenko/Ignatchenko-01.png" /></p>


<h2>References</h2>
<p class="bibliomixed"><a id="[Enet]"></a>[Enet] <a href="http://enet.bespin.org/">http://enet.bespin.org/</a></p>

<p class="bibliomixed"><a id="[Loganberry04]"></a>[Loganberry04]  David â€˜Loganberryâ€™ Buttery, â€˜Frithaes! â€“ an Introduction to Colloquial Lapineâ€™, <a href="http://bitsnbobstones.watershipdown.org/lapine/overview.html">http://bitsnbobstones.watershipdown.org/lapine/overview.html</a></p>

<p class="bibliomixed"><a id="[Masterraghu]"></a>[Masterraghu]  <a href="http://www.masterraghu.com/subjects/np/introduction/unix_network_programming_v1.3/ch24lev1sec2.html">http://www.masterraghu.com/subjects/np/introduction/unix_network_programming_v1.3/ch24lev1sec2.html</a></p>

<p class="bibliomixed"><a id="[Mondal]"></a>[Mondal] Amit Mondal, Aleksandar Kuzmanovic, â€˜Removing Exponential Backoff from TCPâ€™, <em>ACM SIGCOMM Computer Communication Review</em></p>

<p class="bibliomixed"><a id="[NoBugs15]"></a>[NoBugs15]  â€˜64 Network DOâ€™s and DONâ€™Ts for Game Engines. Part IV. Great TCP-vs-UDP Debateâ€™ <a href="http://ithare.com/64-network-dos-and-donts-for-game-engines-part-iv-great-tcp-vs-udp-debate/">http://ithare.com/64-network-dos-and-donts-for-game-engines-part-iv-great-tcp-vs-udp-debate/</a> </p>

<p class="bibliomixed"><a id="[NoBugs15a]"></a>[NoBugs15a]  â€˜64 Network DOâ€™s and DONâ€™Ts for Game Engines. Part VI. TCPâ€™ <a href="http://ithare.com/64-network-dos-and-donts-for-multi-player-game-developers-part-vi-tcp/">http://ithare.com/64-network-dos-and-donts-for-multi-player-game-developers-part-vi-tcp/</a> </p>

<p class="bibliomixed"><a id="[RakNet]"></a>[RakNet]  <a href="https://github.com/OculusVR/RakNet">https://github.com/OculusVR/RakNet</a></p>

<p class="bibliomixed"><a id="[Stevens]"></a>[Stevens]  W. Richard Stevens, Bill Fenner, Andrew M. Rudoff, <em>UNIXÂ® Network Programming Volume 1, Third Edition: The Sockets Networking API </em></p>

<p class="bibliomixed"><a id="[UDT]"></a>[UDT]  <a href="http://udt.sourceforge.net/">http://udt.sourceforge.net/</a></p>

<h2>Acknowledgement</h2>

<p class="bibliomixed">Cartoon by Sergey Gordeev from Gordeev Animation Graphics, Prague.</p>

<p class="footnotes"> </p>

<ol>
	<li><a id="FN01"></a>For simplicity, the discussion of flow control and TCP windows is omitted; so are the optimizations such as <code>SACK</code> and fast retransmit</li>

	<li><a id="FN02"></a>Alternatively, if the socket is non-blocking, in this situation <code>send()</code> can return <code>EWOULDBLOCK</code></li>

	<li><a id="FN03"></a>In practice, <code>ACK</code> is not necessarily a separate packet; efforts are taken by the TCP stack to â€˜piggy-backâ€™ an <code>ACK</code> on any packet going in the needed direction</li>

	<li><a id="FN04"></a>There are other mechanisms of re-sending, which include re-sending when an <code>ACK</code> was received, but was out-of-order, but they are beyond the scope of present article</li>
</ol>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
