# ch17: Transmission Control Protocol

![17.TCP](https://tva1.sinaimg.cn/large/007S8ZIlly1ggrwggjez0j30x40u0afo.jpg)

## 1. Services

TCP提供面向连接的、可靠的字节流服务。

TCP通过如下的方式来提供可靠性：

* 数据被分割成TCP认为合适的数据块，叫做segment；
* TCP发送一个segment之后会启动一个定时器，超时重传；
* TCP收到数据后会发送一个ack来确认；
* TCP会计算header和data的checksum；
* TCP保持数据的传输顺序；
* TCP如果数据报重复，会丢弃重复数据；
* TCP还提供流量控制。

## 2. Header

TCP的数据封装在IP datagram中：

![](https://tva1.sinaimg.cn/large/007S8ZIlly1ggrvhnhjuzj30yo0dqwg7.jpg)

Header的格式如下：

![](https://tva1.sinaimg.cn/large/007S8ZIlly1ggrvi0iko9j31240qodit.jpg)

如果没有options的话，header的大小是20个字节。

* 源端口、目的端口，加上源IP和目的IP，共同定义一个TCP连接（也叫socket）；
* 序号用来标识TCP发送的字节流，标识这个segment的第一个字节，是一个32位的无符号数；
* 建立连接的时候SYN标识打开，然后发送TCP数据的主机选择一个initial sequence number（ISN），然后ISN加1作为这个序号，因为SYN也消费一个序号；
* 每一个传输的字节都被序号了，确认序号就是接收方希望发送方发送的下一个字节号，这个字段之后ACK打开的时候才有效；
* 发送ACK不需要消耗序列号，所以连接打开的时候ACK一直处于打开状态；
* TCP提供双全工服务，数据可以在一个连接上双向流动，所以连接两端都需要维护一个序列号；
* TCP头部最大是60个字节；

### 2.1 Flags

TCP里有6个标志位：

| Flag | Description                                                               |
| ---- | ------------------------------------------------------------------------- |
| URG  | The urgent pointer is valid                                               |
| ACK  | The acknowledgment number is valid                                        |
| PSH  | The receiver should pass this data to the application as soon as possible |
| RST  | Reset the connection                                                      |
| SYN  | Synchronize sequence numbers to initiate a connection                     |
| FIN  | The sender is finished sending data                                       |

* TCP通过一个窗口大小（window size）来提供流量控制；
* 窗口大小的单位是byte，长度是16位，所以最大的窗口是65535字节；
* 校验和包含了header和data，计算方式和UDP的类似；
* 当URG打开的时候紧急指针（urgent pointer）才有效，是一个正的偏移量，和序号的值相加表示紧急数据的最后一个字节的序号，用来发送紧急数据；
* 最常见的可选项是最长报文大小，maximum segment size，MSS。连接建立的第一个segment中设置这个字段的值，它指明了本端所能接收的最大长度的报文段；
* TCP segment数据可以为空，当建立连接和终止连接的时候，segment只有header。如果以防没有数据要发送，也使用没有任何数据的首部来确认收到的数据。在处理超时的时候，会发送这种segment。
