带外(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(默认情况下):
- Winsock 服务提供程序向客户端通知FD_OOB事件(如果客户端注册了 WSPAsyncSelect通知),FD_READ用于通知是否存在正常数据的方式完全相同。 也就是说,当 OOB 数据到达且以前没有 OOB 数据排队,并且使用 MSG_OOB 标志读取数据时,也会发布FD_OOB,在读取作返回后仍要读取某些 OOB 数据。 不会为 OOB 数据发布FD_READ消息。
- Winsock 服务提供程序从 WSPSelect 返回,如果 OOB 数据排在套接字上排队,则 套接字集的相应 除外。
- 客户端可以通过MSG_OOB调用 WSPRecv,随时读取紧急数据块。 OOB 数据的块会跳转队列。
- 客户端无需MSG_OOB即可调用 WSPRecv 来读取正常的数据流。 OOB 数据块不会显示在数据流中,其中包含普通数据。 如果在调用 WSPRecv后仍保留 OOB 数据,则服务提供商会在使用 WSPSelect时通过 FD_OOB 或通过 通知客户端,但 除外。
- 对于 OOB 数据在正常数据流中的位置的协议,单个 WSPRecv作不会跨越该位置。 一个 WSPRecv 将返回标记前的正常数据,第二个 WSPRecv 在标记后开始读取数据。
启用SO_OOBINLINE:
- FD_OOB消息不针对 OOB 数据发布, 为了 WSPSelect 和 WSPAsyncSelect 函数,OOB 数据被视为正常数据,并通过分别在 自述 或发送FD_READ消息来指示套接字。
- 客户端可能无法调用 WSPRecv,其MSG_OOB标志设置为读取 OOB 数据块, 将返回错误代码 WSAEINVAL。
- 客户端可以在未设置MSG_OOB标志的情况下调用 WSPRecv。 任何 OOB 数据都将按正常数据流中的正确顺序传送。 OOB 数据永远不会与普通数据混合 - 必须有三个读取请求才能超过 OOB 数据。 第一个返回 OOB 数据块之前的普通数据,第二个返回 OOB 数据,第三个返回 OOB 数据之后的正常数据。 换句话说,将保留 OOB 数据块边界。
WSPAsyncSelect 例程特别适用于在关闭SO_OOBINLINE时处理 OOB 数据的通知。