理论上,数据可以与 SYN 一起发送,但在连接状态为 ESTABLISHED 之前不应传递给应用程序。引用RFC 793 第 3.4 节 - “建立连接”:
以下是连接启动的几个示例。尽管这些示例没有显示使用携带数据的段进行连接同步,但这是完全合法的,只要接收 TCP 在明确数据有效之前不将数据传递给用户(即,必须缓冲数据)直到连接达到 ESTABLISHED 状态)。
这意味着客户端和服务器理论上都可以在 SYN 内发送数据。但是只有在收到最终的 ACK 并因此在服务器端达到 ESTABLISHED 时,客户端数据才应该传送到服务器应用程序。而在 SYN+ACK 中来自服务器的数据可以立即传递给客户端,因为一旦收到 SYN+ACK,客户端状态就已建立,从 RFC 中的示例可以看出:
TCP A TCP B
1. CLOSED LISTEN
2. SYN-SENT --> <SEQ=100><CTL=SYN> --> SYN-RECEIVED
3. ESTABLISHED <-- <SEQ=300><ACK=101><CTL=SYN,ACK> <-- SYN-RECEIVED
4. ESTABLISHED --> <SEQ=101><ACK=301><CTL=ACK> --> ESTABLISHED
5. ESTABLISHED --> <SEQ=101><ACK=301><CTL=ACK><DATA> --> ESTABLISHED
使用 TCP 快速打开,在某些情况下甚至可以消除客户端的限制。
但通常 TCP 握手中不包含任何数据,因为默认的套接字 API 不支持这种用例:只有一个connect
在客户端和服务器端进行握手accept
,两者都不能在内部传递任何数据握手。