【发布时间】:2012-02-27 12:59:54
【问题描述】:
我试图了解带有标志PSH 和带有标志URG 的TCP 段之间的区别。
我阅读了 RFC,但仍然无法得到它,其中一个是否在将数据发送到进程之前缓冲数据而另一个没有?
【问题讨论】:
标签: tcp
我试图了解带有标志PSH 和带有标志URG 的TCP 段之间的区别。
我阅读了 RFC,但仍然无法得到它,其中一个是否在将数据发送到进程之前缓冲数据而另一个没有?
【问题讨论】:
标签: tcp
我不会太严格地接受 RFC 中的所有内容,这些标志的实现似乎有些模棱两可。 URG 涉及在填充缓冲区之前发送数据包,而 PSH 控制在接收端将数据向上移动到堆栈中。
【讨论】:
它们是两种截然不同的机制。
###PSH 和 PUSH 函数
当您发送数据时,您的TCP 会缓冲它。因此,如果您发送一个字符,它不会立即发送它,而是等待看看您是否还有更多。但也许您希望它直接上网:这就是 PUSH 功能的用武之地。如果您 PUSH 数据,您的 TCP 将立即创建一个段(或几个段)并推送它们。
但故事并不止于此。当对等 TCP 接收到数据时,它会自然地对它们进行缓冲它不会对每个字节都干扰应用程序。这就是PSH 标志的作用。如果接收 TCP 看到 PSH 标志,它将立即推送数据到应用程序。
没有用于设置 PSH 标志的 API。通常它是由内核在清空缓冲区时设置的。来自 TCP/IP 图解:
该标志通常用于指示发送数据包一侧的缓冲区已 与发送数据包一起清空。也就是说,当设置了 PSH 位域的数据包离开发送方时,发送方就没有更多的数据可以发送了。
但请注意,史蒂文斯也说过:
推送(接收方应尽快将此数据传递给应用程序 可能——没有可靠地实现或使用)
###URG 和 OOB 数据
TCP 是一种面向流的协议。因此,如果您在一侧推送 64K 字节,您最终将在另一侧获得 64k 字节。所以想象一下你推送了很多数据,然后有一些消息说“嘿,你知道我刚刚发送的所有数据吗?是的,把它扔掉”。问题的要点是,一旦您在连接上推送数据,您必须等待接收方获取所有数据,然后才能获取新数据。
这就是URG 标志的作用所在。当您发送紧急数据时,您的 TCP 会创建一个特殊的段,在该段中设置 URG 标志以及紧急指针字段。这会导致接收 TCP 在单独的通道上将紧急数据转发给应用程序(例如,在 Unix 上,您的进程会收到 SIGURG)。这允许应用程序处理带外数据¹。
附带说明,重要的是要注意紧急数据现在很少使用并且实施得不好。使用单独的渠道或完全不同的方法要容易得多。
¹:RFC 6093 不同意这种“带外”的用法,并表示:
TCP 紧急机制不是发送“带外”的机制 数据:所谓的“紧急数据”应该“在线”传递给 TCP 用户。
然后它继续承认:
默认情况下,“紧急数据”的最后一个字节是“带外”传送的 到应用程序。也就是说,它不是作为 正常的数据流。
应用程序必须竭尽全力并指定例如SO_OOBINLINE 获取符合标准的紧急语义。
如果这一切听起来很复杂,请不要使用紧急数据。
【讨论】:
在已经回答的问题上添加更多信息。
URG 位,如果设置了数据优先级,这意味着不是等待整个字节流在“紧急”数据之前传输,而是紧急数据将在紧急基础上发送并且不会等待其前面的整个字节流被传输。
当设置URG 位时,也会设置紧急指针(在TCP 标头选项字段中:16 位)。
URG 指针告诉已经到达的段中有多少字节的数据是紧急的。 (例如,如果数据大小是 100 字节,并且只有前 50 个字节是紧急的,那么紧急指针的值为 50)。
现在来到PSH 位。 PSH 位的目的是告诉 TCP 不要等待缓冲区变满并立即发送数据。类似地,当接收方接收到带有PSH标志的段时,应该立即将数据发送到上层,而不是等待接收缓冲区变满。这方面的实际示例是 telnet 应用程序,其中应用程序以几次击键的形式发送数据。如果 telnet 等待缓冲区变满,然后将数据传输到接收方,它将变得不可用。
【讨论】: