SPI 中的协议独立带数据

带外 (OOB) 数据是与连接的流套接字配对关联的逻辑独立传输通道。 OOB 数据可以独立于普通数据传送给用户。 抽象定义 OOB 数据设施必须支持一次至少一个 OOB 数据块的可靠传送。 此数据块可能包含至少一个字节的数据,并且至少一个 OOB 数据块可能随时等待向用户传递。 对于支持带内信号 ((即 TCP)的通信协议,其中紧急数据按顺序传送到正常数据) ,系统通常会从正常数据流中提取 OOB 数据并将其单独存储, (在正常数据流) 留下空白。 这样,用户就可以按顺序选择接收 OOB 数据并按顺序接收 OOB 数据,而无需缓冲所有干预数据。 可以查看 OOB 数据。

用户可以确定是否有任何 OOB 数据等待使用 WSPIoctl (SIOCATMARK) 函数进行读取。 对于在正常数据流中 OOB 数据块的位置概念有意义的协议,即 TCP () ,Windows套接字服务提供程序将维护一个概念标记,指示 OOB 数据在正常数据流中最后一个字节的位置。 这不需要实现 WSPIoctl (SIOCATMARK) 功能, OOB 数据的存在或缺失都是必需的。

对于在正常数据流中 OOB 数据块的位置概念有意义的协议,应用程序可能更喜欢在正常数据流中处理带外数据。 这是通过设置套接字选项来实现的,SO_OOBINLINE (请参阅 WSPIoctl) 部分。 对于 OOB 数据块真正独立于正常数据流的其他协议,尝试设置SO_OOBINLINE将导致错误。 应用程序可以使用 SIOCATMARK WSPIoctl 命令来确定标记前面是否有任何未读的 OOB 数据。 例如,它可能使用此方式与对等方重新同步,方法是确保适当时丢弃数据流中标记的所有数据。

默认情况下,禁用SO_OOBINLINE () :

  • 如果客户端向 WSPAsyncSelect 注册了通知,则 Winsock 服务提供商会通知客户端FD_OOB事件,这与FD_READ用于通知是否存在正常数据的方式完全相同。 也就是说,当 OOB 数据到达且以前没有 OOB 数据排队,并且使用 MSG_OOB 标志读取数据时,也会发布FD_OOB,并且某些 OOB 数据在读取操作返回后仍要读取。 不会为 OOB 数据发布FD_READ消息。
  • 如果 OOB 数据在套接字上排队,则 Winsock 服务提供程序从 WSPSelect 返回相应的 例外 套接字集。
  • 客户端可以使用 MSG_OOB 调用 WSPRecv ,随时读取紧急数据块。 OOB 数据的块会跳转队列。
  • 客户端无需MSG_OOB即可调用 WSPRecv 来读取正常数据流。 OOB 数据块不会显示在数据流中使用普通数据。 如果在对 WSPRecv 的任何调用后仍保留 OOB 数据,则服务提供商会在使用 WSPSelect 时向客户端发出FD_OOB或通过 exceptfd 通知客户端。
  • 对于 OOB 数据在正常数据流中具有位置的协议,单个 WSPRecv 操作不会跨越该位置。 一个 WSPRecv 将返回标记前的正常数据,第二个 WSPRecv 需要开始读取标记后的数据。

启用SO_OOBINLINE:

  • FD_OOB 对于 WSPSelect 和 WSPAsyncSelect 函数,OOB 数据不会针对 OOB 数据发布,并且会分别在自述或发送FD_READ消息中设置套接字来指示 OOB 数据。
  • 客户端可能无法使用设置为读取 OOB 数据块的MSG_OOB标志调用 WSPRecv , 将返回错误代码 WSAEINVAL。
  • 客户端可以在未设置MSG_OOB标志的情况下调用 WSPRecv 。 任何 OOB 数据都将按正常数据流中的正确顺序传送。 OOB 数据永远不会与普通数据混合 - 必须有三个读取请求才能超过 OOB 数据。 第一个返回 OOB 数据块之前的正常数据,第二个返回 OOB 数据,第三个返回 OOB 数据之后的正常数据。 换句话说,将保留 OOB 数据块边界。

WSPAsyncSelect 例程特别适用于在关闭SO_OOBINLINE时处理 OOB 数据的通知。