331 lines
11 KiB
HTML
331 lines
11 KiB
HTML
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||
|
|
||
|
<!-- TCPss.html (C) K. J. Turner 18/12/14 -->
|
||
|
|
||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||
|
|
||
|
<head>
|
||
|
|
||
|
<title>Transmission Control Protocol (Slow Start)</title>
|
||
|
|
||
|
<link rev="made" href="http://www.cs.stir.ac.uk/~kjt/"/>
|
||
|
|
||
|
<script type="text/javascript" language="JavaScript">
|
||
|
|
||
|
<!--
|
||
|
|
||
|
var simulator;
|
||
|
var userAMessageSize;
|
||
|
var userAMessageSizeOld = 100;
|
||
|
var userBMessageSize;
|
||
|
var userBMessageSizeOld = 300;
|
||
|
var windowSizeA;
|
||
|
var windowSizeAOld = 500;
|
||
|
var windowSizeB;
|
||
|
var windowSizeBOld = 400;
|
||
|
var maxSendPacket;
|
||
|
var maxSendPacketOld = 200;
|
||
|
|
||
|
function validInteger(name, value, min, max) {
|
||
|
if (!value.match("\\d+") || value < min || value > max) {
|
||
|
alert("Value for " + name + " must be in range " + min + " to " + max);
|
||
|
return false;
|
||
|
}
|
||
|
else
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
function validFloat(name, value, min, max) {
|
||
|
if (!value.match("\\d+\.\\d+") || value < min || value > max) {
|
||
|
alert("Value for " + name + " must be in range " + min + " to " + max);
|
||
|
return false;
|
||
|
}
|
||
|
else
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
function set() {
|
||
|
userAMessageSize = document.settings.userAMessageSize.value;
|
||
|
userBMessageSize = document.settings.userBMessageSize.value;
|
||
|
windowSizeA = document.settings.windowSizeA.value;
|
||
|
windowSizeB = document.settings.windowSizeB.value;
|
||
|
maxSendPacket = document.settings.maxSendPacket.value;
|
||
|
lossRate = document.settings.lossRate.value;
|
||
|
if (validInteger("User A Message Size", userAMessageSize, 10, 1000) &&
|
||
|
validInteger("User B Message Size", userBMessageSize, 10, 1000) &&
|
||
|
validInteger("Protocol A Receive Window", windowSizeA, 10, 1000) &&
|
||
|
validInteger("Protocol B Receive Window", windowSizeB, 10, 1000) &&
|
||
|
validInteger("Medium Maximum Packet Size", maxSendPacket, 10, 1000) &&
|
||
|
validFloat("Loss Rate", lossRate, 0.0, 1.0)) {
|
||
|
if (userAMessageSize != userAMessageSizeOld ||
|
||
|
userBMessageSize != userBMessageSizeOld ||
|
||
|
windowSizeA != windowSizeAOld ||
|
||
|
windowSizeB != windowSizeBOld ||
|
||
|
maxSendPacket != maxSendPacketOld)
|
||
|
simulator.restart();
|
||
|
userAMessageSizeOld = userAMessageSize;
|
||
|
userBMessageSizeOld = userBMessageSize;
|
||
|
windowSizeAOld = windowSizeA;
|
||
|
windowSizeBOld = windowSizeB;
|
||
|
maxSendPacketOld = maxSendPacket;
|
||
|
simulator.setParameter("userAMessageSize", userAMessageSize);
|
||
|
simulator.setParameter("userBMessageSize", userBMessageSize);
|
||
|
simulator.setParameter("windowSizeA", windowSizeA);
|
||
|
simulator.setParameter("windowSizeB", windowSizeB);
|
||
|
simulator.setParameter("maxSendPacket", maxSendPacket);
|
||
|
simulator.setParameter("lossRate", lossRate);
|
||
|
simulator.updateActionList();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-->
|
||
|
|
||
|
</script>
|
||
|
|
||
|
</head>
|
||
|
|
||
|
<body background="simulator.jpeg"
|
||
|
onload="simulator=document.ProtocolSimulator; set();">
|
||
|
|
||
|
<div style="text-align: center">
|
||
|
|
||
|
<h1>
|
||
|
Transmission Control Protocol Simulator
|
||
|
<br/>
|
||
|
(Slow Start)
|
||
|
</h1>
|
||
|
|
||
|
<img src="simulator.gif" alt="Simulator Logo"/>
|
||
|
|
||
|
</div>
|
||
|
|
||
|
<h2>Protocol Description</h2>
|
||
|
|
||
|
<p>
|
||
|
TCP (Transmission Control Protocol) is a connection-oriented protocol for
|
||
|
transferring data reliably in either direction between a pair of users. TCP
|
||
|
is a rather complex protocol, so it is easy to lose track of the simulation.
|
||
|
Try not to do anything too complicated! There are <a
|
||
|
href="TCPcs.html">client-server</a> and <a href="TCPpp.html">peer-peer</a>
|
||
|
simulations as alternatives that illustrate opening and closing connections.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
This simulation focuses on dynamic window management - specifically what is
|
||
|
called "slow start". This is designed to avoid the protocol
|
||
|
flooding the network with packets when it starts, and to ensure that the
|
||
|
protocol recovers slowly following message loss and timeout due to
|
||
|
congestion.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
Users simply send messages of a fixed size; the content of messages is not
|
||
|
identified. The medium maximum packet size is the protocol segment size.
|
||
|
Depending on this, messages may be sent as a number of fragments. Data
|
||
|
transfer is also subject to the current window size of the receiver, and may
|
||
|
be held up if the receiver's window becomes full.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
When data arrives, it is not immediately delivered to the receiving user.
|
||
|
Instead, data is accumulated and can be delivered later ("Deliver
|
||
|
octets to user"). If the receiving window becomes full, new requests to
|
||
|
send data will be buffered. When the receiving window opens again, this
|
||
|
buffered data can be sent ("Send octets to peer").
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
Messages may contain a send sequence number (the offset of where the message
|
||
|
starts in the user's octet stream), an acknowledgement sequence number
|
||
|
(the offset of the next octet expected), and the current window (how many
|
||
|
octets can be received).
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
Slow start is governed by two protocol variables: <var>cwind</var>
|
||
|
(congestion window) and <var>ssthresh</var> (slow start threshold). These
|
||
|
are measured in octets for this simulation, but are sometimes counted as
|
||
|
numbers of segments. (Multiply the number of segments by the segment size to
|
||
|
get the number of octets.) The slow start procedure operates as follows:
|
||
|
</p>
|
||
|
|
||
|
<dl>
|
||
|
|
||
|
<dt><b>Initial Phase</b></dt>
|
||
|
<dd>
|
||
|
The minimum of the congestion window size and the receiver window size
|
||
|
determines how much data can be sent. The protocol starts conservatively
|
||
|
with <var>cwind</var> set to the segment size. As each acknowledgement
|
||
|
arrives, <var>cwind</var> is increased by the segment size. The amount of
|
||
|
data that can be sent thus typically doubles in each round-trip time (i.e.
|
||
|
the time to send a message and get a response). The amount is ultimately
|
||
|
limited by the receiver's window. The available window thus increases
|
||
|
exponentially (shown as "exp." in the simulation when
|
||
|
<var>cwind</var> is increased).
|
||
|
</dd>
|
||
|
|
||
|
<dt><b>Congestion Action</b></dt>
|
||
|
<dd>
|
||
|
When a timeout occurs and the protocol has to retransmit, the congestion
|
||
|
window is set back to one segment size. At this point, the threshold
|
||
|
<var>ssthresh</var> is set to half the previous value of
|
||
|
<var>cwind</var>. Suppose that the segment size is 200, so that
|
||
|
<var>cwind</var> starts at 200. On subsequent acknowledgements,
|
||
|
<var>cwind</var> could rise to 1600. If congestion causes loss at this
|
||
|
point, <var>cwind</var> will be set back to 200 and <var>ssthresh</var>
|
||
|
will be set to 800 (half of 1600).
|
||
|
</dd>
|
||
|
|
||
|
<dt><b>Congestion Recovery</b></dt>
|
||
|
<dd>
|
||
|
Now the window is built up exponentially again. Once it reaches
|
||
|
<var>ssthresh</var>, it is no longer increased so aggressively. Instead,
|
||
|
<var>cwind</var> increases by one segment size for each round-trip time.
|
||
|
This is irrespective of how many acknowledgements arrive during this
|
||
|
period, unlike the exponential phase where every acknowledgement causes
|
||
|
the window to double per round trip time. During the recovery phase, the
|
||
|
available window increases linearly (shown as "lin." in the
|
||
|
simulation). The window will then become 900, 1000, etc. up to the
|
||
|
receiver maximum. If congestion again causes loss, the procedure is
|
||
|
repeated.
|
||
|
</dd>
|
||
|
|
||
|
</dl>
|
||
|
|
||
|
<p>
|
||
|
Because the simulation does not run in real time, it does not reflect
|
||
|
round-trip times. As a result, its behaviour during the exponential and
|
||
|
linear phases appears similar. However, the phase is indicated depending on
|
||
|
whether <var>cwind</var> is below or above the threshold.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
TCP is rather complex, so the simulation does not attempt to faithfully
|
||
|
reflect all its details. Although the main paths should work as expected, it
|
||
|
may be possible to get the simulation into unusual states in which it does
|
||
|
not behave correctly.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
Things the simulation does not cover include the following. See advanced
|
||
|
guides to TCP for more information.
|
||
|
</p>
|
||
|
|
||
|
<ul>
|
||
|
|
||
|
<li>advanced congestion control</li>
|
||
|
|
||
|
<li>handling duplicate acknowledgements</li>
|
||
|
|
||
|
<li>fast retransmit</li>
|
||
|
|
||
|
<li>fast recovery</li>
|
||
|
|
||
|
</ul>
|
||
|
|
||
|
<h2>Protocol Parameters</h2>
|
||
|
|
||
|
<p>
|
||
|
The following settings are adequate for a simple simulation. For a more
|
||
|
advanced exploration, choose different options and click <em>Change
|
||
|
Settings</em>. This may cause the simulation to restart.
|
||
|
</p>
|
||
|
|
||
|
<form name="settings">
|
||
|
|
||
|
<center>
|
||
|
|
||
|
<table cellpadding="5">
|
||
|
|
||
|
<tr>
|
||
|
<td align="right">User A Message Size (10 to 1000):</td>
|
||
|
<td>
|
||
|
<input type="text" name="userAMessageSize" value="800" size="4"/>
|
||
|
</td>
|
||
|
</tr>
|
||
|
|
||
|
<tr>
|
||
|
<td align="right">User B Message Size (10 to 1000):</td>
|
||
|
<td><input name="userBMessageSize" size="4" value="800"/> </td>
|
||
|
</tr>
|
||
|
|
||
|
<tr>
|
||
|
<td align="right">Protocol A Receive Window (10 to 1000):</td>
|
||
|
<td><input type="text" name="windowSizeA" value="1000" size="4"/></td>
|
||
|
</tr>
|
||
|
|
||
|
<tr>
|
||
|
<td align="right">Protocol B Receive Window (10 to 1000):</td>
|
||
|
<td><input type="text" name="windowSizeB" value="1000" size="4"/></td>
|
||
|
</tr>
|
||
|
|
||
|
<tr>
|
||
|
<td align="right">Medium/Protocol Segment Size (10 to 1000):</td>
|
||
|
<td>
|
||
|
<input type="text" name="maxSendPacket" value="200" size="4"/>
|
||
|
</td>
|
||
|
</tr>
|
||
|
|
||
|
<tr>
|
||
|
<td align="right">Loss Rate (0.0 = lose none, 1.0 = lose any):</td>
|
||
|
<td><input type="text" name="lossRate" value="0.2" size="4"/> </td>
|
||
|
</tr>
|
||
|
|
||
|
<tr>
|
||
|
<td align="center" colspan="2">
|
||
|
<input type="button" name="btnSet" value="Change Settings"
|
||
|
onclick="set()"/>
|
||
|
</td>
|
||
|
</tr>
|
||
|
|
||
|
</table>
|
||
|
|
||
|
</center>
|
||
|
|
||
|
</form>
|
||
|
|
||
|
<script type="text/javascript" language="JavaScript">
|
||
|
|
||
|
<!--
|
||
|
|
||
|
// initialise settings from the above and not the default protocol settings
|
||
|
|
||
|
set();
|
||
|
|
||
|
//-->
|
||
|
|
||
|
</script>
|
||
|
|
||
|
<h2>Protocol Simulation</h2>
|
||
|
|
||
|
<p>
|
||
|
The protocol simulation shows a time-sequence diagram with two peer service
|
||
|
users, protocol entities that support them, and a communications medium
|
||
|
(network) that carries messages. The connection phase is not shown in this
|
||
|
simulation as it is assumed to have just occurred. Equally, the
|
||
|
disconnection phase is not shown.
|
||
|
</p>
|
||
|
|
||
|
<center>
|
||
|
|
||
|
<applet code="simulator.ProtocolSimulator.class"
|
||
|
archive="ProtocolSimulator.jar" width="750" height="700"
|
||
|
name="ProtocolSimulator">
|
||
|
<param name="protocol" value="TCP/ss"/>
|
||
|
</applet>
|
||
|
|
||
|
</center>
|
||
|
|
||
|
<hr/>
|
||
|
|
||
|
<p>
|
||
|
<a href="index.html"><img src="uparrow.gif" alt="Up Arrow"/></a>
|
||
|
Up one level to <a href="index.html">Protocol Simulators</a>
|
||
|
</p>
|
||
|
|
||
|
</body>
|
||
|
|
||
|
</html>
|
||
|
|