> For the complete documentation index, see [llms.txt](https://valineliu.gitbook.io/deuterium-wiki/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://valineliu.gitbook.io/deuterium-wiki/reading/cs-jing-dian-shu-ji/tcpv1/ch-19-tcp-interactive-data-flow.md).

# ch 19: TCP Interactive Data Flow

![19.TCP Interactive Data Flow](https://tva1.sinaimg.cn/large/007S8ZIlly1ggzka4ifg3j31an0gvq4d.jpg)

## 1. Interactive Input

TCP传输的数据有两种，一中是交互式的数据，一种是成块的数据。

从segment的数量来看，交互式的和块式的segment数据包大概各占一半。

从数据大小来说，交互式的大概占10%，块式的大概占90%。

这里先看看交互式的数据。

## 2. Delayed Acknowledgments

交互式的数据中，IP header加上TCP header基本上就已经40个字节了，而交互式的数据一半都很少，大概10个字节左右，这样数据包就很浪费。

为了减少segment的数量，一般都会将ack推迟一会，等接收到更多的数据的时候再ack。

一般的实现都是将ack推迟**200ms**。

比如：

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

## 3. Nagle Algorithm

如果这种小的segment多的话，可能会对网络造成阻塞，这个时候可以使用Nagle算法。

这个算法要求，一个TCP连接上最多只能有一个未被确认的未完成的segment，在这个segment未被ack之前不能发送其余的segment。

优点：自适应（self-clocking），ack越快，发送数据也就越快。

**对ack的理解**：

* ack仅仅表示TCP已经正确接收了数据；
* 不代表数据已经被应用层接收；
* 未被应用层接收的数据放在TCP的缓存中；
* 未被应用层接收的数据会影响接收窗口的大小；
* 从接收窗口可以得到有多少数据未被应用层接收。

有的时候需要数据尽快发送，而不需要等待前一个ack，这个时候就需要禁用Nagle算法。

API中可以通过TCP\_NODELAY来禁用。
