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

whi*_*fox 55 tcp

我试图理解TCP段与标志PSH和标志之间的区别URG.我读了RFC但仍然无法得到它,其中一个是否在将数据发送到进程之前缓冲数据而另一个没有?

cni*_*tar 103

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

PSH和PUSH功能

发送数据时,TCP缓冲它.因此,如果您发送一个角色,它将不会立即发送,而是等待您是否有更多.但也许你想让它直接上线:这就是PUSH功能的用武之地.如果你推送数据你的TCP将立即创建一个段(或几个段)并推送它们.

但故事并不止于此.当对等TCP接收数据时,它自然会缓冲它们,它不会干扰每个字节的应用程序.这是PSH标志启动的地方.如果接收TCP看到PSH标志,它将立即数据送到应用程序.

没有用于设置PSH标志的API .通常,它在清空缓冲区时由内核设置.来自TCP/IP Illustrated:

该标志通常用于指示发送分组的一侧的缓冲器已经与发送分组一起清空.换句话说,当设置了PSH位字段的数据包离开发送方时,发送方没有更多数据要发送.

但请注意史蒂文斯还说:

推送(接收方应尽快将此数据传递给应用程序 - 不能可靠地实施或使用)

URG和OOB数据

TCP是面向流的协议.因此,如果你在一侧推动64K字节,你最终将获得64k字节.所以想象一下你推了很多数据,然后有一些消息说:"嘿,你知道我刚发送的所有数据吗?是的,扔掉它".问题的关键是,一旦你在连接上推送数据,就必须等待接收器在获取新数据之前获取所有数据.

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


作为旁注,重要的是要意识到紧急数据在今天很少使用,并且没有很好地实施.使用单独的通道或完全不同的方法要容易得多.


¹:RFC 6093不同意这种"带外"的使用并指出:

TCP紧急机制不是发送"带外"数据的机制:所谓的"紧急数据"应该"在线"传递给TCP用户.

但随后它继续承认:

默认情况下,"紧急数据"的最后一个字节"带外"传送到应用程序.也就是说,它不作为普通数据流的一部分提供.

应用程序必须不受影响,并指定例如SO_OOBINLINE获得符合标准的紧急语义.

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

  • @apenwarr没有API.我在答案中添加了一些细节. (2认同)
  • @Matteo我修改了答案.最后,RFC强调指定的紧急机制确实是内联的,但实际上默认情况下所有实现都提供带外语义.随意编辑更多. (2认同)

Sum*_*han 7

在已经回答的问题中添加更多信息.

  • URG位如果设置优先级数据,意味着由此而不是等待在"紧急"数据之前发送的整个字节流,紧急数据将被紧急发送并且不会等待整个字节流在它之前传播.

  • 当该URG位置位时,还设置了紧急指针(在TCP标题选项字段中:16位).

  • URG指针指示已到达的段中数据的紧急字节数.(例如,如果数据大小为100字节且仅紧急50字节,则紧急指针的值为50).

  • 现在来了URG.该PSH位的目的是告诉TCP不要等待缓冲区变满并立即发送数据.类似地,当接收器接收到设置了PSH标志的段时,应立即将数据发送到上层而不等待接收缓冲器变满.这方面的实际例子是telnet应用程序,其中应用程序以几次击键的形式发送数据.如果等待缓冲区变满,则telnet将变为不可用,然后将数据传输到接收器.