【问题标题】:TCP handshake: at which point exactly the connection is considered established and data can be sent?TCP握手:在什么时候认为连接已建立并且可以发送数据?
【发布时间】:2018-08-05 15:38:11
【问题描述】:

TCP 3 次握手由 SYN、SYN-ACK 和 ACK 数据包组成。

我的问题是:服务器(即接受连接的服务器)是否可以在发送 SYN-ACK 后立即发送数据,或者在收到第一个 ACK​​ 之前什么都不能发送?

换句话说,如果服务器在接受连接后立即在套接字上发送数据,客户端需要多少次往返才能开始接收它。是否只是 1 次往返(即来自客户端的 SYN,以及来自服务器的 SYN-ACK + 数据包)?或者至少 2 次往返?

【问题讨论】:

    标签: tcp


    【解决方案1】:

    接受的答案并不完全正确。有两种情况没有解决。

    第一个是 TCP 快速打开。这是在 RFC 7413 中定义的。它专门设计用于允许服务器开始处理在 SYN 上发送的数据,甚至在 SYN ACK 中发送响应数据,而不需要三次握手的最终 ACK。

    第二个是 RFC 793 for TCP 实际上确实允许 SYN 上的数据;但是,在连接完成之前,不会处理此数据(快速打开除外)。如果连接永远不会完成,则数据显然会被丢弃。

    【讨论】:

    • 感谢您的完整回答。我的目标是在 TCP 上设计一个具有最小延迟的协议。我猜 T/TCP 不适用于我的情况,因为数据实际上并没有传递到服务器。您知道 TFO 的可用性吗?当前的ios/android平台是否支持?
    【解决方案2】:

    在最终的 ACK 之前,服务器无法发送任何内容,因为在此之前它没有接受的套接字。 accept() 在握手完成之前不会返回。

    【讨论】:

    • 谢谢,在我看来也是这样,但我不确定。你确定吗?
    • 如果我不确定我不会发布它。真正让我不快的一件事是被要求确认或重申我已经说过的事情。
    • 那么您能指出是什么让您对此充满信心吗?我知道理论上在发送 SYN+ACK 后,TCP 状态机进入 SYN_RECEIVED 状态。然而,似乎报告应用程序接受的连接并立即发送数据实际上没有问题。为了最大限度地减少延迟,这实际上是有道理的。
    • 您的回答不完整。 SYN 上的数据是 RFC 允许的。阅读我的附加答案。
    【解决方案3】:

    当客户端发送第一个同步数据包时,客户端将处于 SYN_SENT 状态,并等待来自服务器的 SYN/ACK。 服务器将继续侦听套接字。当它收到 SYN 时,服务器进入 SYN_REVD 状态。现在它向客户端发送 SYN/ACK 并分配缓冲区并设置变量,如 congwin 、 threshold 等......当客户端收到 SYN/ACK 时,它会进入 ESTABLISHED STATE 并使用 ACK 确认服务器。现在客户端可以在 ack 段中发送数据或不发送数据。服务器收到 ack 后进入建立状态。 现在客户端和服务器都处于建立状态,可以交换数据了。

    当客户端收到 SYN/ACK 时,它会在自己这边分配缓冲区和变量,然后向服务器发送 ACK。

    要了解这些状态,请尝试在 linux 中使用 netstat 命令,您可以看到套接字的状态

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-22
      • 2012-05-07
      • 2019-10-17
      • 2023-01-30
      • 1970-01-01
      • 2011-04-21
      • 1970-01-01
      • 2019-04-04
      相关资源
      最近更新 更多