Protocol-Independent dati fuori banda
L'astrazione del socket di flusso include la nozione di dati fuori banda (OOB). Molti protocolli consentono di contrassegnare parti di dati in ingresso come speciali in qualche modo e questi blocchi di dati speciali possono essere recapitati all'utente fuori dalla sequenza normale. Gli esempi includono dati accelerati in X.25 e altri protocolli OSI e dati urgenti nell'uso di TCP di BSD UNIX. La sezione seguente descrive la gestione dei dati OOB in modo indipendente dal protocollo. Una discussione sui dati OOB implementati usando i dati urgenti TCP segue la spiegazione indipendente dal protocollo. In ogni discussione, l'uso di recv implica anche recvfrom, WSARecve WSARecvFrome i riferimenti a WSAAsyncSelect si applicano anche a WSAEventSelect.
Dati OOB indipendenti dal protocollo
I dati OOB sono un canale di trasmissione logicamente indipendente associato a ogni coppia di socket di flusso connessi. I dati OOB possono essere recapitati all'utente indipendentemente dai dati normali. L'astrazione definisce che le strutture dati OOB devono supportare il recapito affidabile di almeno un blocco di dati OOB alla volta. Questo blocco di dati può contenere almeno un byte di dati e almeno un blocco di dati OOB può essere in attesa di recapito all'utente in qualsiasi momento. Per i protocolli di comunicazione che supportano la segnalazione in banda (ad esempio TCP, dove i dati urgenti vengono recapitati in sequenza con i dati normali), il sistema estrae normalmente i dati OOB dal normale flusso di dati e li archivia separatamente (lasciando un gap nel normale flusso di dati). In questo modo gli utenti possono scegliere tra ricevere i dati OOB in ordine e riceverli fuori sequenza senza dover memorizzare nel buffer tutti i dati intermedi. È possibile visualizzare i dati fuori banda (OOB).
Un utente può determinare se i dati OOB sono in attesa di essere letti usando la funzione ioctlsocket o WSAIoctl con la funzione SIOCATMARK IOCTL. Per i protocolli in cui il concetto di posizione del blocco di dati OOB all'interno del flusso di dati normale è significativo, ad esempio TCP, un provider di servizi Windows Sockets mantiene un marcatore concettuale che indica la posizione dell'ultimo byte dei dati OOB all'interno del normale flusso di dati. Non è necessario per l'implementazione delle funzioni di ioctlsocket o WSAIoct l che supportano SIOCATMARK. La presenza o l'assenza di dati OOB è tutto obbligatorio.
Per i protocolli in cui il concetto di posizione del blocco di dati OOB all'interno del normale flusso di dati è significativo, un'applicazione potrebbe elaborare dati fuori banda inline, come parte del normale flusso di dati. Questa operazione viene ottenuta impostando l'opzione socket SO_OOBINLINE con la funzionesetockopt. Per altri protocolli in cui i blocchi di dati OOB sono realmente indipendenti dal normale flusso di dati, il tentativo di impostare SO_OOBINLINE genera un errore. Un'applicazione può usare la funzioneioctlsocketo WSAIoctl con la funzione SIOCATMARK IOCTL per determinare se sono presenti dati OOB non letti prima del contrassegno. Ad esempio, può usare queste informazioni per risincronizzare con il peer assicurando che tutti i dati fino al contrassegno nel flusso di dati vengano eliminati quando appropriato.
Con SO_OOBINLINE disabilitato (impostazione predefinita):
- Windows Sockets notifica a un'applicazione di un evento FD_OOB, se l'applicazione registrata per la notifica con WSAAsyncSelect, nello stesso modo in cui FD_READ viene usata per notificare la presenza di dati normali. Ovvero, FD_OOB viene pubblicato quando i dati OOB arrivano senza dati OOB in precedenza accodati. Il FD_OOB viene inoltre pubblicato quando i dati vengono letti usando il flag MSG_OOB mentre alcuni dati OOB rimangono in coda dopo la restituzione dell'operazione di lettura. FD_READ i messaggi non vengono pubblicati per i dati OOB.
- Windows Sockets restituisce da selezionare con il appropriato eccettofds socket impostato se i dati OOB vengono accodati sul socket.
- L'applicazione può chiamare con MSG_OOB per leggere il blocco di dati urgente in qualsiasi momento. Il blocco di dati OOB salta la coda.
- L'applicazione può chiamare senza MSG_OOB per leggere il normale flusso di dati. Il blocco di dati OOB non viene visualizzato nel flusso di dati con dati normali. Se i dati OOB rimangono dopo qualsiasi chiamata a recv, Windows Sockets invia una notifica all'applicazione con FD_OOB o con exceptfds quando si usa selezionare.
- Per i protocolli in cui i dati OOB hanno una posizione all'interno del normale flusso di dati, una singola operazione recv non si estende su tale posizione. Una restituisce i dati normali prima del contrassegno e un secondo recv è necessario per iniziare a leggere i dati dopo il contrassegno.
Con SO_OOBINLINE abilitato:
- FD_OOB i messaggi non vengono pubblicati per i dati OOB. I dati OOB vengono considerati normali ai fini del selezionare e funzioni WSAAsyncSelect e indicate impostando il socket rispettivamente in readfds o inviando un messaggio di FD_READ.
- L'applicazione non può chiamare con il flag MSG_OOB impostato per leggere il blocco di dati OOB. Viene restituito il codice di errore WSAEINVAL.
- L'applicazione può chiamare recv senza il flag MSG_OOB impostato. Tutti i dati OOB vengono recapitati nell'ordine corretto all'interno del normale flusso di dati. I dati OOB non sono mai misti ai dati normali. Devono essere presenti tre richieste di lettura per superare i dati OOB. Il primo restituisce i dati normali prima del blocco di dati OOB, il secondo restituisce i dati OOB, il terzo restituisce i dati normali dopo i dati OOB. In altre parole, i limiti dei blocchi di dati OOB vengono mantenuti.
La routine WSAAsyncSelect è particolarmente adatta alla gestione della notifica della presenza di dati fuori banda quando SO_OOBINLINE è disattivata.
Dati OOB in TCP
Importante
La discussione seguente sui dati fuori banda (OOB), implementata usando i dati urgenti TCP, segue il modello usato nella distribuzione del software Berkeley. Gli utenti e gli implementatori devono tenere presente che:
Attualmente ci sono due interpretazioni in conflitto di RFC 793 (dove viene introdotto il concetto).
L'implementazione dei dati OOB in Berkeley Software Distribution (BSD) non è conforme ai requisiti host specificati in RFC 1122.
In particolare, il puntatore URGENTE TCP in BSD punta al byte dopo il byte di dati urgente e un puntatore TCP conforme a RFC punta al byte di dati urgente urgente. Di conseguenza, se un'applicazione invia dati urgenti da un'implementazione compatibile con BSD a un'implementazione compatibile con RFC 1122, il ricevitore legge il byte urgente errato (legge il byte che si trova dopo il byte corretto nel flusso di dati come byte urgente).
Per ridurre al minimo i problemi di interoperabilità, i writer di applicazioni sono invitati a non usare i dati OOB a meno che non sia necessario per interagire con un servizio esistente. I fornitori di Windows Sockets sono invitati a documentare la semantica OOB (BSD o RFC 1122) implementata dal prodotto.
L'arrivo di un segmento TCP con il flag URG (per urgente) indica l'esistenza di un singolo byte di dati OOB all'interno del flusso di dati TCP. Il blocco di dati OOB è di un byte. Il puntatore urgente è un offset positivo rispetto al numero di sequenza corrente nell'intestazione TCP che indica la posizione del blocco di dati OOB (ambiguamente, come indicato nell'esempio precedente). Potrebbe quindi puntare a dati che non sono ancora stati ricevuti.
Se SO_OOBINLINE è disabilitato (impostazione predefinita) quando arriva il segmento TCP contenente il byte a cui punta il puntatore urgente, il blocco di dati OOB (un byte) viene rimosso dal flusso di dati e memorizzato nel buffer. Se un segmento TCP successivo arriva con il flag urgente impostato (e un nuovo puntatore urgente), il byte OOB attualmente in coda può essere perso perché viene sostituito dal nuovo blocco di dati OOB (come avviene in Berkeley Software Distribution). Tuttavia, non viene mai sostituito nel flusso di dati.
Con SO_OOBINLINE abilitato, i dati urgenti rimangono nel flusso di dati. Di conseguenza, il blocco di dati OOB non viene mai perso quando arriva un nuovo segmento TCP contenente dati urgenti. Il contrassegno dati OOB esistente viene aggiornato alla nuova posizione.
Nota
Quando viene impostata l'opzione socket SO_OOBINLINE, i dati IOCTL SIOCATMARK restituiscono sempre TRUEe i dati OOB vengono restituiti all'utente come dati normali.