分类: 系统运维
2012-06-18 17:53:30
The window size is relative to the acknowledged sequence number. The
sender computes its usable window, which is how much data it can send
immediately.
Over time this sliding window moves to the right, as
the receiver acknowledges data. The relative motion of the two ends of
the window increases or decreases the size of the window. Three terms
are used to describe the movement of the right and left edges of the
window.
1. The window closes as the left edge advances to the right. This happens when data is sent and acknowledged.
2. The window opens when the right edge moves to the right,
allowing more data to be sent. This happens when the receiving process
on the other end reads acknowledged data, freeing up space in its TCP
receive buffer.
3. The window shrinks when the right edge moves to the left. The
Host Requirements RFC strongly discourages this, but TCP must be able to
cope with a peer that does this.
The left edge of the
window cannot move to the left, because this edge is controlled by the
acknowledgment number received from the other end. If an ACK were
received
that implied moving the left edge to the left, it is a duplicate ACK, and discarded.
If the left edge reaches the right edge, it is called a zero window. This stops the sender from transmitting any data.
There are numerous points:
1. The sender does not have to transmit a full window's worth of data.
2. One segment from the receiver acknowledges data and slides the window to the right. This is because the window size is relative to the acknowledged sequence number.
3. The size of the window can decrease, but the right edge of the window must not move leftward.
4. The receiver does not have to wait for the window to fill before
sending an ACK. Many implementations send an ACK for every two segments
that are received.
Window Size
The size of the
window offered by the receiver can usually be controlled by the
receiving process. This can affect the TCP performance.
PUSH Flag
It's
a notification from the sender to the receiver for the receiver to pass
all the data that it has to the receiving process. This data would
consist of whatever is in the segment with the PUSH flag, along with any
other data the receiving TCP has collected for the receiving process.
In
the original TCP specification, it was assumed that the programming
interface would allow the sending process to tell its TCP when to set
the PUSH flag. In an interactive application, for example, when the
client sent a command to the server, the client would set the PUSH flag
and wait for the server's response. By allowing the client application
to tell its TCP to set the flag, it was a notification to the client's
TCP that the client process didn't want the data to hang around in the
TCP buffer, waiting for additional data, before sending a segment to the
server. Similarly, when the server's TCP received the segment with the
PUSH flag, it was a notification to pass the data to the server process
and not wait to see if any additional data arrives.
Today,
however, most APIs don't provide a way for the application to tell its
TCP to set the PUSH flag. Indeed, many implementors feel the need for
the PUSH flag is outdated, and a good TCP implementation can determine
when to set the flag by itself.
Most Berkeley-derived implementations automatically set the PUSH
flag if the data in the segment being sent empties the send buffer. This
means we normally see the PUSH flag set for each application write,
because data is usually sent when it's written.
Berkeley-derived
implementations ignore a received PUSH flag because they normally never
delay the delivery of received data to the application.
Slow Start
TCP is now
required to support an algorithm called slow start. It operates by
observing that the rate at which new packets should be injected into the
network is the rate at which the acknowledgments are returned by the
other end.
Slow start adds another window to the sender's TCP: the congestion
window, called cwnd. When a new connection is established with a host on
another network, the congestion window is initialized to one segment
(i.e., the segment size announced by the other end). Each time an ACK is
received, the congestion window is increased by one segment, (cwnd is
maintained in bytes, but slow start always increments it by the segment
size.) The sender can transmit up to the minimum of the congestion
window
and the advertised window. The congestion window is flow
control imposed by the sender, while the advertised window is flow
control imposed by the receiver.
The sender starts by
transmitting one segment and waiting for its ACK. When that ACK is
received, the congestion window is incremented from one to two, and two
segments can be sent. When each of those two segments is acknowledged,
the congestion window is increased to four. This provides an exponential
increase.
At some point the capacity of the internet can be
reached, and an intermediate router will start discarding packets. This
tells the sender that its congestion window has gotten too large.
Urgent Mode
TCP
provides what it calls urgent mode, allowing one end to tell the other
end that "urgent data" of some form has been placed into the normal
stream of data. The other end is notified that this urgent data has been
placed into the data stream, and it's up to the receiving end to decide
what to do.
The notification from one end to the other that urgent data exists in
the data stream is done by setting two fields in the TCP header. The
URG bit is turned on and the 16-bit urgent pointer is set to a positive
offset that must be added to the sequence number field in the TCP header
to obtain the sequence number of the last byte of urgent data.
TCP
must inform the receiving process when an urgent pointer is received
and one was not already pending on the connection, or if the urgent
pointer advances in the data stream. The receiving application can then
read the data stream and must be able to tell when the urgent pointer is
encountered. As long as data exists from the receiver's current read
position until the urgent pointer, the application is considered to be
in an "urgent mode." After the urgent pointer is passed, the application
returns to its normal mode.
TCP itself says little more about
urgent data. There is no way to specify where the urgent data starts in
the data stream. The only information sent across the connection by TCP
is that urgent mode has begun (the URG bit in the TCP header) and the
pointer to the last byte of urgent data. Everything else is left to the
application.
Unfortunately many implementations incorrectly call TCP's urgent
mode out-of-band data. If an application really wants a separate
out-of-band channel, a second TCP connection is the easiest way to
accomplish this. (Some transport layers do provide what most people
consider true out-of-band data: a logically separate data path using the
same connection as the normal data path. This is not what TCP
provides.)