首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么TCP连接中的发起者需要ACK?

为什么TCP连接中的发起者需要ACK?
EN

Network Engineering用户
提问于 2016-10-31 18:22:25
回答 3查看 1.3K关注 0票数 3

问题不是此链接的翻版。因为这会问为什么我们需要3路握手,我知道为什么!我的问题是为什么ACK数据包不能被下面的协议包(PSH ACK)所容纳。

我明白为什么我们需要握手,但我们最终需要ACK吗?让我们以一个http查询为例,然后是TCP握手。

代码语言:javascript
复制
CLIENT:23434 SN 0 -----> SERVER:80 -- SYN
CLIENT:23434 <----- SERVER:80 SN 0, AN 1 -- SYN ACK
CLIENT:23434 SN 1 AN 1 -----> SERVER:80 -- ACK
CLIENT:23434 SN 1 AN 1 -----> SERVER:80 -- PSH ACK(HTTP GET)

如果有一个协议(数据)包,然后是具有相同序列号和确认号的三路握手的ACK,为什么不使用该协议分组来同步呢?

EN

回答 3

Network Engineering用户

发布于 2016-10-31 20:21:56

问得好。我同意这不是与另一个重复。

三方握手的目的是建立双向沟通渠道.在该通道内发生的通信超出了TCP的范围。

有时,会建立一个连接,以便客户端向服务器发送一些东西。其他情况下,建立连接是为了让服务器向客户端发送一些东西。TCP必须说明这两种情况。

为了简单起见,重新引用您的通信插图,并添加行号:

代码语言:javascript
复制
#1   SN 0 -----> SERVER:80 -- SYN
#2   <----- SERVER:80 SN 0, AN 1 -- SYN ACK
#3   SN 1 AN 1 -----> SERVER:80 -- ACK
#4   SN 1 AN 1 -----> SERVER:80 -- PSH ACK(HTTP GET)

如果使用TCP的协议行为类似HTTP,连接建立后的第一次数据传输是客户端向服务器发送数据,那么您可以正确地说,单独的ACK (第3行)似乎是多余的。后面的数据包(第4行)就足以告诉服务器客户端收到了它们的ISN (来自第2行)。

然而,并不是所有的协议都像HTTP --有些协议意味着服务器在连接建立后立即发送数据。在这种情况下,服务器必须等待客户端发送空确认包,才能获得成功建立双向通信信道并开始数据传输的肯定确认。

这在互联网上比较少见,但它确实存在。顺便说一下,我可以想到被动FTP,客户端启动数据连接(也就是发送初始SYN),但连接的目的是服务器发送初始数据包--在建立数据连接后立即启动。

对于某些协议,TCP不能采用一种方式,对于其他协议,TCP不能采用另一种方式。因此,必须发送空确认,以便对这两种情况进行说明。

票数 4
EN

Network Engineering用户

发布于 2016-10-31 20:55:03

听起来你是在问为什么,如果客户端首先发送数据,客户端就不能将简单的握手与数据结合起来。

但我认为它可以-它只是一般不这样做。操作系统API是典型的原因。当套接字不处于已建立的状态时,通常不会接受写()n的数据,而且内核一看到syn/ ack,就不会等待用户空间在发送ack之前发送一些数据。(因为内核不知道这个bidi连接的哪个端将先写,而另一端在完成握手之前不能写)。

如果一个系统在这一点上确实在握手的第三部分发送数据,违背这种传统,他们很可能会发现他们在这样做时有互操作的问题。因此,试图推波助澜是一种抑制因素。

票数 2
EN

Network Engineering用户

发布于 2016-11-01 12:28:34

是的,需要空的ack来确认从另一端发送的syn。

代码语言:javascript
复制
(closed) A <syn>----------> B (listen) 
(syn-sent) A <------------<syn><ack> B (listen) 
(established) A               B (syn-sent)

在这些步骤B等待来自A的ACK作为SYN,以达到连接建立状态。

但是,您在这里讨论的有趣的情况是,尽可能减少下一步的可能性。

代码语言:javascript
复制
  (established) A <ack>-----------> B (syn-sent)
  (established) A [data>]<ack>-----------> B (established)

使用

代码语言:javascript
复制
 (established) A [<data>]<ack>-----------> B (syn-sent)

但看起来,B处于未确定的状态--它似乎不考虑有效载荷

在RFC 793 (第3.4节)中。建立连接)

下面是连接启动的几个例子。虽然这些示例没有显示使用数据承载段的连接同步,但这是完全合法的,只要接收TCP在数据有效之前不将数据传递给用户(也就是说,数据必须在接收方缓冲,直到连接达到既定状态)。

所以从rfc看来

4 SN 1 AN 1 -----> SERVER:80 -- PSH ACK(HTTP GET)

将被缓冲,并且只有在随后出现一个空ack之后才会将其传递给应用程序。

您的解决方案可能适用于称为延迟ack的实现。

票数 1
EN
页面原文内容由Network Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://networkengineering.stackexchange.com/questions/36205

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档