TCP 中推送标志和紧急标志之间的区别

问题描述 投票:0回答:3

我试图理解带有

PSH
标志的 TCP 段和带有
URG
标志的 TCP 段之间的区别。 我阅读了 RFC 但仍然无法获取它,其中一个在将数据发送到进程之前是否缓冲数据,而另一个则没有?

tcp
3个回答
116
投票

它们是两种截然不同的机制。

PSH 和 PUSH 功能

当您发送数据时,您的

TCP
会对其进行缓冲。因此,如果您发送一个字符,它不会立即发送,而是等待查看是否有更多字符。但也许您希望它直接在线:这就是 PUSH 功能的用武之地。如果您 PUSH 数据,您的 TCP 将立即创建一个段(或几个段)并push它们。

但故事并没有就此结束。当对等 TCP 接收到数据时,它会自然地缓冲它们不会干扰每个字节的应用程序。这就是

PSH
标志发挥作用的地方。如果接收 TCP 看到 PSH 标志,它将立即将数据push 到应用程序。

没有 API 可以设置

PSH
标志。通常它是由内核清空缓冲区时设置的。来自 TCP/IP 图解:

该标志通常用于指示发送数据包一侧的缓冲区已被使用 与发送数据包的同时清空。换句话说,当设置了 PSH 位字段的数据包离开发送方时,发送方没有更多数据可发送。

但请注意史蒂文斯也说:

推送(接收者应尽快将此数据传递给应用程序) 可能—未可靠实施或使用

URG 和 OOB 数据

TCP 是一种面向流的协议。因此,如果您在一侧推送 64K 字节,最终您将在另一侧获得 64K 字节。因此,想象一下您推送了大量数据,然后收到一些消息,上面写着“嘿,您知道我刚刚发送的所有数据吗?是的,把它们扔掉”。问题的要点是,一旦您在连接上推送数据,您就必须等待接收方获取所有数据,然后才能获取新数据。

这就是

URG
标志发挥作用的地方。当您发送紧急数据时,TCP 会创建一个特殊的段,在其中设置 URG 标志以及紧急指针字段。这会导致接收 TCP 在单独的通道上将紧急数据转发到应用程序(例如,在 Unix 上,您的进程会收到
SIGURG
)。这允许应用程序处理数据带外


顺便说一句,重要的是要意识到紧急数据现在很少使用并且没有得到很好的实施。使用单独的渠道或完全不同的方法要容易得多。

¹:RFC 6093

不同意这种“带外”的使用,并指出:

TCP紧急机制不是发送“带外”的机制 数据:所谓的“紧急数据”应“在线”交付给 TCP 用户。

但随后它又承认:

默认情况下,“紧急数据”的最后一个字节是“带外”传送的 到应用程序。也就是说,它不作为 正常数据流。

应用程序必须特意指定,例如
SO_OOBINLINE

获得符合标准的紧急语义。

如果这一切听起来很复杂,只是不要使用紧急数据


9
投票

在已回答的基础上添加更多信息。
  • 如果设置了
    URG

    位,则优先考虑数据,这意味着紧急数据将紧急发送,而不是等待“紧急”数据之前的整个字节流被传输,而不会等待用于传输前面的整个字节流。
  • URG
     位被设置时,紧急指针也被设置(在 
    TCP

    标头选项字段中:16 位)。
  • URG

    指针告诉已到达的段中有多少字节的数据是紧急的。 (例如,如果数据大小为 100 字节,并且只有前 50 字节是紧急的,则紧急指针的值为 50)。
  • 现在来到
    PSH
    位。 
    PSH
    位的目的是告诉TCP不要等待缓冲区变满并立即发送数据。同样,当接收方收到设置了
    PSH

    标志的报文段时,应立即将数据发送到上层,而无需等待接收缓冲区变满。实际的例子是 telnet 应用程序,其中应用程序以很少的击键形式发送数据。如果 telnet 等待缓冲区变满后再将数据传输到接收方,那么 telnet 将无法使用。

1
投票

我不会过于严格地接受 RFC 中的所有内容,这些标志的实现似乎存在一些含糊之处。 URG 涉及在填充缓冲区之前发送数据包,而 PSH 控制在接收端将数据向上移动到堆栈。

© www.soinside.com 2019 - 2024. All rights reserved.