# Computer Network

## TCP/IP

1. 为什么 ack=seq+1 而不是 ack=seq?\
   通过查询资料和所学内容，我们知道： 1. 三次握手的前两次握手，client和server会根据一定的算法(连接四元组和时间戳还有Security Number)生成ISS。 2. 三次握手的后两次握手，client和server分别会对对方发过来的SYN进行应答，在ack序列上等于seq+1。 3. 后面传输数据的时候，sender发送len长度的data，receiver就会将ack(receiver)=seq(sender)+len(sender)。

   所以说，3中接收到多少数据就讲多少数据长度的len加在seq上是一个正常的行为，问题出在2的确认SYN中为什么将ack=seq+1，搜索到结果有如下几个： 1. SYN和FIN也是需要确认的信息，所以需要占据一个seq，表示该信息已经被确认，不需要重传。 2. 如果SYN和FIN不占据一个seq，对于FIN而言，四次挥手的第二三次server的挥手除了FLAG外其他其实是一样的，即一样的ack，可能也有一样的seq(没有数据需要传输的情况下)，可能导致client段无法分辨第二次挥手的ACK和第三次挥手的FIN。

   Notice that the acknowledgement number has been increased by 1 although no payload data has yet been sent by the client. This is because the presence of the SYN or FIN flag in a received packet triggers an increase of 1 in the sequence. (This does not interfere with the accounting of payload data, because packets with the SYN or FIN flag set do not carry a payload.)

   注：收到的报文中只有ACK时不需要将seq+1。
2. TCP传输中ACK的优化\
   已经知道的有延迟ACK，还有就是ACK和需要传输的数据一起过去，SO上面已经有大佬画了图：

   ```
   Before ACK Optimization:   
    +-------------------------------------------------------+
    |     client           network            server        |
    +-----------------+                +--------------------|
    |    (connect)    | ---- SYN ----> |                    |
    |                 | <-- SYN,ACK -- |     (accepted)     |
    |   (connected)   | ---- ACK ----> |                    |
    \_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/

    when client sends...
    \_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/
    |                 |                |                    |
    |     (send)      | ---- data ---> |                    |
    |                 | <---- ACK ---- |  (data received)   |
    \_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/

    when server sends...
    \_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/
    |                 |                |                    |
    |                 | <--- data ---- |       (send)       |
    | (data received) | ---- ACK ----> |                    |
    \_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/

    ...and so on, til the connection is shut down or reset

    =========================================================
    =========================================================
    After ACK Optimization:
    \_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/
    |                 |                |                    |
    |                 | <--- data ---- |       (send)       |
    | (data received) |                |                    |
    |     (send)      | -- data,ACK -> |                    |
    |                 |                |  (data received)   |
    |                 | <- data,ACK -- |       (send)       |
    | (data received) |                |                    |
    |  (wait a bit)   | <--- data ---- |       (send)       |
    | (data received) |                |                    |
    |     (send)      | -- data,ACK -> |                    |
    |                 |                |  (data received)   |
    |     (send)      | ---- data ---> |   (wait a bit)     |
    |                 |                |  (data received)   |
    |                 | <- data,ACK -- |       (send)       |
    | (data received) |                |                    |
    |  (wait a bit)   |   (dead air)   |                    |
    |                 | ---- ACK ----> |                    |
    \_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/
   ```
3. TCP Connection State Diagram in rfc793   &#x20;

   ```
                              +---------+ ---------\      active OPEN
                              |  CLOSED |            \    -----------
                              +---------+<---------\   \   create TCB
                                |     ^              \   \  snd SYN
                   passive OPEN |     |   CLOSE        \   \
                   ------------ |     | ----------       \   \
                    create TCB  |     | delete TCB         \   \
                                V     |                      \   \
                              +---------+            CLOSE    |    \
                              |  LISTEN |          ---------- |     |
                              +---------+          delete TCB |     |
                   rcv SYN      |     |     SEND              |     |
                  -----------   |     |    -------            |     V
   +---------+      snd SYN,ACK  /       \   snd SYN          +---------+
   |         |<-----------------           ------------------>|         |
   |   SYN   |                    rcv SYN                     |   SYN   |
   |   RCVD  |<-----------------------------------------------|   SENT  |
   |         |                    snd ACK                     |         |
   |         |------------------           -------------------|         |
   +---------+   rcv ACK of SYN  \       /  rcv SYN,ACK       +---------+
   |           --------------   |     |   -----------
   |                  x         |     |     snd ACK
   |                            V     V
   |  CLOSE                   +---------+
   | -------                  |  ESTAB  |
   | snd FIN                  +---------+
   |                   CLOSE    |     |    rcv FIN
   V                  -------   |     |    -------
   +---------+          snd FIN  /       \   snd ACK          +---------+
   |  FIN    |<-----------------           ------------------>|  CLOSE  |
   | WAIT-1  |------------------                              |   WAIT  |
   +---------+          rcv FIN  \                            +---------+
   | rcv ACK of FIN   -------   |                            CLOSE  |
   | --------------   snd ACK   |                           ------- |
   V        x                   V                           snd FIN V
   +---------+                  +---------+                   +---------+
   |FINWAIT-2|                  | CLOSING |                   | LAST-ACK|
   +---------+                  +---------+                   +---------+
   |                rcv ACK of FIN |                 rcv ACK of FIN |
   |  rcv FIN       -------------- |    Timeout=2MSL -------------- |
   |  -------              x       V    ------------        x       V
    \ snd ACK                 +---------+delete TCB         +---------+
     ------------------------>|TIME WAIT|------------------>| CLOSED  |
                              +---------+                   +---------+
   ```

## Reference

1. [StackOverflow | Does TCP send a SYN/ACK on every packet or only on the first connection?](https://stackoverflow.com/questions/3604485/does-tcp-send-a-syn-ack-on-every-packet-or-only-on-the-first-connection?rq=1\&newreg=b5892dcf2e9e453685c3dd626d1c5082)
2. [Understanding TCP Sequence and Acknowledgment Numbers](https://packetlife.net/blog/2010/jun/7/understanding-tcp-sequence-acknowledgment-numbers/)
3. [Why does an pure ACK increment the sequence number?](https://networkengineering.stackexchange.com/questions/48775/why-does-an-pure-ack-increment-the-sequence-number)
4. [RFC 793](https://tools.ietf.org/html/rfc793)
