Protocol-Independent datos fuera de banda
La abstracción del socket de flujo incluye la noción de datos fuera de banda (OOB). Muchos protocolos permiten que partes de los datos entrantes se marquen como especiales de alguna manera, y estos bloques de datos especiales se pueden entregar al usuario fuera de la secuencia normal. Entre los ejemplos se incluyen los datos acelerados en X.25 y otros protocolos OSI, y los datos urgentes en el uso de TCP de BSD UNIX. En la sección siguiente se describe el control de datos de OOB de forma independiente del protocolo. Una explicación de los datos de OOB implementados mediante datos urgentes de TCP sigue la explicación independiente del protocolo. En cada discusión, el uso de recv también implica recvfrom, WSARecv y WSARecvFrom, y las referencias a WSAAsyncSelect también se aplican a WSAEventSelect.
Datos de OOB independientes del protocolo
Los datos OOB son un canal de transmisión lógicamente independiente asociado a cada par de sockets de flujo conectados. Los datos OOB se pueden entregar al usuario independientemente de los datos normales. La abstracción define que las instalaciones de datos de OOB deben admitir la entrega confiable de al menos un bloque de datos OOB a la vez. Este bloque de datos puede contener al menos un byte de datos y al menos un bloque de datos OOB puede estar pendiente de entrega al usuario en cualquier momento. En el caso de los protocolos de comunicaciones que admiten la señalización en banda (como TCP, donde los datos urgentes se entregan en secuencia con los datos normales), el sistema normalmente extrae los datos OOB del flujo de datos normal y los almacena por separado (dejando una brecha en el flujo de datos normal). Esto permite a los usuarios elegir entre recibir los datos OOB en orden y recibirlos fuera de secuencia sin tener que almacenar en búfer todos los datos intermedios. Es posible echar un vistazo a los datos fuera de banda (OOB).
Un usuario puede determinar si algún dato de OOB está esperando que se lea mediante la función ioctlsocket o WSAIoctl con el IOCTL SIOCATMARK . Para los protocolos en los que el concepto de la posición del bloque de datos OOB dentro del flujo de datos normal es significativo, como TCP, un proveedor de servicios de Windows Sockets mantiene un marcador conceptual que indica la posición del último byte de datos OOB dentro del flujo de datos normal. Esto no es necesario para la implementación de las funciones ioctlsocket o WSAIoctl que admiten SIOCATMARK. Se requiere la presencia o ausencia de datos de OOB.
En el caso de los protocolos en los que el concepto de la posición del bloque de datos OOB dentro del flujo de datos normal es significativo, una aplicación podría procesar datos fuera de banda insertados, como parte del flujo de datos normal. Esto se logra estableciendo la opción de socket SO_OOBINLINE con la función setsockopt . Para otros protocolos en los que los bloques de datos OOB son realmente independientes del flujo de datos normal, al intentar establecer SO_OOBINLINE se produce un error. Una aplicación puede usar la función ioctlsocket o WSAIoctl con el IOCTL SIOCATMARK para determinar si hay datos OOB no leídos que preceden a la marca. Por ejemplo, puede usar esta información para resincronizar con su elemento del mismo nivel asegurándose de que todos los datos hasta la marca del flujo de datos se descartan cuando corresponda.
Con SO_OOBINLINE deshabilitado (configuración predeterminada):
- Windows Sockets notifica a una aplicación de un evento de FD_OOB, si la aplicación registrada para la notificación con WSAAsyncSelect, de la misma manera que FD_READ se usa para notificar la presencia de datos normales. Es decir, FD_OOB se publica cuando los datos de OOB llegan sin datos de OOB previamente en cola. El FD_OOB también se publica cuando los datos se leen mediante la marca MSG_OOB mientras algunos datos de OOB permanecen en cola después de que se haya devuelto la operación de lectura. FD_READ mensajes no se publican para los datos de OOB.
- Windows Sockets devuelve de select con el conjunto de sockets exceptfds adecuado si los datos OOB se ponen en cola en el socket.
- La aplicación puede llamar a recv con MSG_OOB para leer el bloque de datos urgente en cualquier momento. El bloque de datos de OOB salta la cola.
- La aplicación puede llamar a recv sin MSG_OOB para leer el flujo de datos normal. El bloque de datos OOB no aparece en el flujo de datos con datos normales. Si los datos de OOB permanecen después de cualquier llamada a recv, Windows Sockets notifica a la aplicación con FD_OOB o con exceptfds al usar select.
- En el caso de los protocolos en los que los datos de OOB tienen una posición dentro del flujo de datos normal, una única operación de recv no abarca esa posición. Un recv devuelve los datos normales antes de la marca y se requiere un segundo recv para empezar a leer los datos después de la marca.
Con SO_OOBINLINE habilitado:
- FD_OOB mensajes no se publican para los datos de OOB. Los datos de OOB se tratan como normales con el fin de las funciones select y WSAAsyncSelect , e indicados estableciendo el socket en readfds o enviando un mensaje de FD_READ respectivamente.
- La aplicación no puede llamar a recv con la marca MSG_OOB establecida para leer el bloque de datos OOB. Se devuelve el código de error WSAEINVAL.
- La aplicación puede llamar a recv sin la marca MSG_OOB establecida. Los datos de OOB se entregan en su orden correcto dentro del flujo de datos normal. Los datos OOB nunca se mezclan con datos normales. Debe haber tres solicitudes de lectura para superar los datos de OOB. La primera devuelve los datos normales antes del bloque de datos OOB, el segundo devuelve los datos OOB; el tercero devuelve los datos normales después de los datos de OOB. En otras palabras, se conservan los límites del bloque de datos OOB.
La rutina WSAAsyncSelect es especialmente adecuada para controlar la presencia de datos fuera de banda cuando SO_OOBINLINE está desactivada.
Datos OOB en TCP
Importante
La siguiente explicación de datos fuera de banda (OOB), implementada mediante datos urgentes de TCP, sigue el modelo utilizado en la distribución de software de Berkeley. Los usuarios e implementadores deben tener en cuenta lo siguiente:
Hay, en la actualidad, dos interpretaciones conflictivas de RFC 793 (donde se introduce el concepto).
La implementación de datos OOB en berkeley Software Distribution (BSD) no se ajusta a los requisitos de host especificados en RFC 1122.
En concreto, el puntero urgente TCP de BSD apunta al byte después del byte de datos urgente y un puntero TCP urgente compatible con RFC apunta al byte de datos urgente urgente. Como resultado, si una aplicación envía datos urgentes de una implementación compatible con BSD a una implementación compatible con RFC 1122, el receptor lee el byte de datos urgente incorrecto (lee el byte ubicado después del byte correcto en el flujo de datos como el byte de datos urgente).
Para minimizar los problemas de interoperabilidad, se recomienda que los escritores de aplicaciones no usen datos de OOB a menos que esto sea necesario para interoperar con un servicio existente. Se insta a los proveedores de Windows Sockets a documentar la semántica de OOB (BSD o RFC 1122) que implementa su producto.
La llegada de un segmento TCP con el conjunto de marcas URG (para urgente) indica la existencia de un único byte de datos OOB dentro del flujo de datos TCP. El bloque de datos OOB tiene un tamaño de byte. El puntero urgente es un desplazamiento positivo del número de secuencia actual en el encabezado TCP que indica la ubicación del bloque de datos OOB (ambiguamente, como se indicó en el anterior). Por lo tanto, podría apuntar a los datos que aún no se han recibido.
Si SO_OOBINLINE está deshabilitado (valor predeterminado) cuando llega el segmento TCP que contiene el byte al que apunta el puntero urgente, el bloque de datos OOB (un byte) se quita del flujo de datos y se almacena en búfer. Si un segmento TCP posterior llega con el conjunto de marcas urgentes (y un nuevo puntero urgente), el byte OOB actualmente en cola se puede perder ya que se reemplaza por el nuevo bloque de datos OOB (como ocurre en Berkeley Software Distribution). Sin embargo, nunca se reemplaza en el flujo de datos.
Con SO_OOBINLINE habilitado, los datos urgentes permanecen en el flujo de datos. Como resultado, el bloque de datos OOB nunca se pierde cuando llega un nuevo segmento TCP que contiene datos urgentes. La marca de datos OOB existente se actualiza a la nueva posición.
Nota:
Cuando se establece la opción de socket SO_OOBINLINE, siOCATMARK IOCTL siempre devuelve TRUE y los datos OOB se devuelven al usuario como datos normales.