IT/Doc

TCP Segment Transfer Example

싸후이 2007. 11. 6. 14:36
Consider the following TCP segment transfer. This has been laid out in a similar format to that which you would see from a Network trace displayed in two-station format. We are just concentrating on the TCP sequence numbers and window sizes:

Type of segment 160.221.172.250 160.221.73.26
SYN Seq.no. 17768656  
  (next seq.no. 17768657)  
  Ack.no. 0  
  Window 8192  
  LEN = 0 bytes  
SYN-ACK   Seq.no. 82980009
    (next seq.no. 82980010)
    Ack.no. 17768657
    Window 8760
    LEN = 0 bytes
ACK Seq.no. 17768657  
  (next seq.no. 17768657)  
  Ack.no. 82980010  
  Window 8760  
  LEN = 0 bytes  
     
     
     
     
     
  Seq.no. 17768657  
  (next seq.no. 17768729)  
  Ack.no. 82980010  
  Window 8760  
  LEN = 72 bytes of data  
    Seq.no. 82980010
    (next seq.no. 82980070)
    Ack.no. 17768729
    Window 8688
    LEN = 60 bytes of data
  Seq.no. 17768729  
  (next seq.no. 17768885)  
  Ack.no. 82980070  
  Window 8700  
  LEN = 156 bytes of data  
    Seq.no. 82980070
    (next seq.no. 82980222)
    Ack.no. 17768885
    Window 8532
    LEN = 152 bytes of data
FIN Seq.no. 17768885  
  (next seq.no. 17768886)  
  Ack.no. 82980222  
  Window 8548  
  LEN = 0 bytes  
FIN-ACK   Seq.no. 82980222
    (next seq.no. 82980223)
    Ack.no. 17768886
    Window 8532
    LEN = 0 bytes
ACK Seq.no. 17768886  
  (next seq.no. 17768886)  
  Ack.no. 82980223  
  Window 8548  
  LEN = 0 bytes  

The value of LEN is the length of the TCP data which is calculated by subtracting the IP and TCP header sizes from the IP datagram size.
  1. The session begins with station 160.221.172.250 initiating a SYN containing the sequence number 17768656 which is the ISS. In addition, the first octet of data contains the next sequence number 17768657. There are only zeros in the Acknowledgement number field as this is not used in the SYN segment. The window size of the sender starts off as 8192 octets as assumed to be acceptable to the receiver.
  2. The receiving station sends both its own ISS (82980009) in the sequence number field and acknowledges the sender's sequence number by incrementing it by 1 (17768657) expecting this to be the starting sequence number of the data bytes that will be sent next by the sender. This is called the SYN-ACK segment. The receiver's window size starts off as 8760.
  3. Once the SYN-ACK has been received, the sender issues an ACK that acknowledges the receiver's ISS by incrementing it by 1 and placing it in the acknowledgement field (82980010). The sender also sends the same sequence number that it sent previously (17768657). This segment is empty of data and we don't want the session just to keep ramping up the sequence numbers unnecessarily. The window size of 8760 is acknowledged by the sender.
  4. From now on ACKs are used until just before the end of the session. The sender now starts sending data by stating the sequence number 17768657 again since this is the sequence number of the first byte of the data that it is sending. Again the acknowledgement number 82980010 is sent which is the expected sequence number of the first byte of data that the receiver will send. In the above scenario, the sender is intitially sending 72 bytes of data in one segment. The network analyser may indicated the next expected sequence number in the trace, in this case this will be 17768657 + 72 = 17768729. The sender has now agreed the window size of 8760 and uses it itself.
  5. The receiver acknowledges the receipt of the data by sending back the number 17768729 in the acknowledgement number field thereby acknowledging that the next byte of data to be sent will begin with sequence number 17768729 (implicit in this is the understanding that sequence numbers up to and including 17768728 have been successfully received). Notice that not every byte needs to be acknowledged. The receiver also sends back the sequence number of the first byte of data in its own segment (82980010) that is to be sent. The receiver is sending 60 bytes of data. The receiver subtracts 72 bytes from its previous window size of 8760 and sends 8688 as its new window size.
  6. The sender acknowledges the receipt of the data with the number 82980070 (82980010 + 60) in the acknowledgement number field, this being the sequence number of the next data byte expected to be received from the receiver. The sender sends 156 bytes of data starting at sequence number 17768729. The sender subtracts 60 bytes from its previous window size of 8760 and sends the new size of 8700.
  7. The receiver acknowledges receipt of this data with the number 17768885 (17768729 + 156) since it was expecting it, and sends 152 bytes of data beginning with the sequence number 82980070. The receiver subtracts 156 bytes from the previous window size of 8688 and sends the new window size of 8532.
  8. The sender acknowledges this with the next expected sequence number 82980070 + 152 = 82980222 and sends the expected sequence number 17768885 in a FIN because at this point the application wants to close the session. The sender subtracts 152 bytes from its previous window size of 8700 and sends the new size of 8548.
  9. The receiver sends an FIN-ACK acknowledging the FIN and increments the acknowledgement sequence number by 1 to 17768886 which is the number it will expect on the final ACK. In addition the receiver sends the expected sequence number 82980223. The window size remains at 8532 as no data was received from the sender's FIN.
  10. The final ACK is sent by the sender confirming the sequence number 17768886 and acknowledges receipt of 1 byte with the acknowledgement number 82980223. The window size finishes at 8548 and the TCP connection is now closed.
From the above you can see that if you have applications where data flow is largely unidirectional, you can have a scenario where there could be a long series of ACKs where the sequence numbers are the same as far as the data receiver is concerned. Also, you may have a frozen window whilst the application catches up which means that in the meantime acknowledgements are sent by the receiver with a window size of 0 until buffer space is freed up and an acknowledgement is sent with the window size ramped up again, thereby allowing the sender to send data again and the sequence numbers start increasing again.

The above example is a clean straightforward bi-directional data transfer session, however you often have multiple TCP sessions to sort through using different ports and sequence numbers, plus in any one session segments could be resent, sent in a row or the window is frozen due to the stack buffer being full all of which can make it interesting tracking sequence numbers. Be aware that the ACK only has to acknowledge the last sequence number received, so if four segments have been sent in a row, only one ACK is required. If sequence numbers do not arrive then the whole segment is lost with all the bytes of data within it, plus any segments that may have been sent in a row before the lost segment.

You will notice in the above example that the window size steadily decreased, this indicates that no data had been processed off the TCP stack by the time the session had finished. On a longer session you should see the window size creep up again as the buffer is emptied by the application. In the example the window sizes could easily be followed because the segment packets followed each other, however most often acknowledgements do not always follow and may be acknowledging more than one segment, this makes it more tricky to follow.

The above description details the simplest case of TCP connections, however you can get more complex scenarios where simultaneous connections are set up, or segments get lost or resent. The judicious use of RST (Reset) helps clean these connections up. You can follow step by step these different scenarios in RFC 793.

'IT > Doc' 카테고리의 다른 글

tcp mechanism  (0) 2014.07.21
ANSI/VT100 Terminal Control  (0) 2008.07.14
tcp 알고리즘  (0) 2007.11.06
Email Disclaimer  (0) 2007.04.24
linux wireless networking guide  (0) 2007.04.05