Share via


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 dei dati in ingresso come speciali in qualche modo e questi blocchi di dati speciali possono essere recapitati all'utente 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, WSARecv e WSARecvFrom e 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, in cui i dati urgenti vengono recapitati in sequenza con i dati normali), il sistema normalmente estrae i dati OOB dal normale flusso di dati e li archivia separatamente (lasciando un gap nel normale flusso di dati). Ciò consente agli utenti di scegliere tra la ricezione dei dati OOB in ordine e la ricezione 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 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 ioctlsocket o WSAIoctl che supportano SIOCATMARK. È necessaria la presenza o l'assenza di dati OOB.

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 funzione setsockopt . 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 funzione ioctlsocket o WSAIoctl con SIOCATMARK IOCTL per determinare se sono presenti dati OOB non letti che precedono il contrassegno. Ad esempio, può usare queste informazioni per risincronizzare con il peer assicurandosi 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 viene usata esattamente come 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 pubblicato anche quando i dati vengono letti usando il flag di MSG_OOB mentre alcuni dati OOB rimangono accodati dopo la restituzione dell'operazione di lettura. FD_READ messaggi non vengono pubblicati per i dati OOB.
  • Windows Sockets restituisce da select con il socket exceptfds appropriato impostato se i dati OOB vengono accodati sul socket.
  • L'applicazione può chiamare recv 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 recv 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 eccezioni quando si usa select.
  • 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. Un recv 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 allo scopo delle funzioni select e WSAAsyncSelect e indicate impostando il socket in readfds o inviando rispettivamente un messaggio FD_READ.
  • L'applicazione non può chiamare recv 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 combinati con i dati normali. Per superare i dati OOB, devono essere presenti tre richieste di lettura. 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 seguente discussione 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:

 

  • Ci sono attualmente 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. 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 di dati urgente errato (legge il byte che si trova dopo il byte corretto nel flusso di dati come byte di dati urgente).

    Per ridurre al minimo i problemi di interoperabilità, è consigliabile che i writer di applicazioni non usino 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 in precedenza). 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 l'opzione socket SO_OOBINLINE è impostata, SIOCATMARK IOCTL restituisce sempre TRUE e i dati OOB vengono restituiti all'utente come dati normali.