Compartilhar via


Protocol-Independent dados fora de banda

A abstração do soquete de fluxo inclui a noção de dados OOB (fora da banda). Muitos protocolos permitem que partes de dados de entrada sejam marcadas como especiais de alguma forma, e esses blocos de dados especiais podem ser entregues ao usuário fora da sequência normal. Exemplos incluem dados acelerados no X.25 e em outros protocolos OSI e dados urgentes no uso de TCP pelo BSD UNIX. A seção a seguir descreve o tratamento de dados OOB de maneira independente do protocolo. Uma discussão sobre dados OOB implementados usando dados urgentes TCP segue a explicação independente do protocolo. Em cada discussão, o uso de recv também implica recvfrom, WSARecve WSARecvFrome referências a WSAAsyncSelect também se aplicam a WSAEventSelect .

Dados OOB independentes do protocolo

Os dados OOB são um canal de transmissão logicamente independente associado a cada par de soquetes de fluxo conectados. Os dados do OOB podem ser entregues ao usuário independentemente dos dados normais. A abstração define que os recursos de dados OOB devem dar suporte à entrega confiável de pelo menos um bloco de dados OOB por vez. Esse bloco de dados pode conter pelo menos um byte de dados, e pelo menos um bloco de dados OOB pode estar aguardando entrega ao usuário a qualquer momento. Para protocolos de comunicação que dão suporte à sinalização em banda (como TCP, em que os dados urgentes são entregues em sequência com os dados normais), o sistema normalmente extrai os dados OOB do fluxo de dados normal e os armazena separadamente (deixando uma lacuna no fluxo de dados normal). Isso permite que os usuários escolham entre receber os dados do OOB em ordem e recebê-los fora de sequência sem precisar armazenar em buffer todos os dados intervenitórios. É possível espiar dados OOB (fora da banda).

Um usuário pode determinar se todos os dados OOB estão aguardando para serem lidos usando a funçãoioctlsocket ou WSAIoctl com o SIOCATMARK IOCTL. Para protocolos em que o conceito da posição do bloco de dados OOB dentro do fluxo de dados normal é significativo, como o TCP, um provedor de serviços do Windows Sockets mantém um marcador conceitual indicando a posição do último byte de dados OOB dentro do fluxo de dados normal. Isso não é necessário para a implementação do ioctlsocket ou funções de WSAIoctl que dão suporte a SIOCATMARK. A presença ou ausência de dados OOB é necessária.

Para protocolos em que o conceito da posição do bloco de dados OOB dentro do fluxo de dados normal é significativo, um aplicativo pode processar dados fora de banda embutidos, como parte do fluxo de dados normal. Isso é feito definindo a opção de soquete SO_OOBINLINE com a função setsockopt. Para outros protocolos em que os blocos de dados OOB são realmente independentes do fluxo de dados normal, tentar definir SO_OOBINLINE resulta em um erro. Um aplicativo pode usar a função ioctlsocket ou WSAIoctl com o SIOCATMARK IOCTL para determinar se há dados OOB não lidos anteriores à marca. Por exemplo, ele pode usar essas informações para ressincronizar com seu par, garantindo que todos os dados até a marca no fluxo de dados sejam descartados quando apropriado.

Com SO_OOBINLINE desabilitado (a configuração padrão):

  • O Windows Sockets notifica um aplicativo de um evento FD_OOB, se o aplicativo registrado para notificação com WSAAsyncSelect, exatamente da mesma maneira que FD_READ é usado para notificar a presença de dados normais. Ou seja, FD_OOB é postado quando os dados do OOB chegam sem dados OOB previamente enfileirados. O FD_OOB também é postado quando os dados são lidos usando o sinalizador MSG_OOB enquanto alguns dados OOB permanecem na fila após o retorno da operação de leitura. FD_READ mensagens não são postadas para dados OOB.
  • O Windows Sockets retorna de selecionar com o apropriado, exceto soquete definido se os dados OOB estiverem na fila no soquete.
  • O aplicativo pode chamar recv com MSG_OOB para ler o bloco de dados urgente a qualquer momento. O bloco de dados OOB pula a fila.
  • O aplicativo pode chamar recv sem MSG_OOB para ler o fluxo de dados normal. O bloco de dados OOB não aparece no fluxo de dados com dados normais. Se os dados do OOB permanecerem após qualquer chamada para recv, os Soquetes do Windows notificarão o aplicativo com FD_OOB ou com , exceto os ao usar selecionar.
  • Para protocolos em que os dados OOB têm uma posição dentro do fluxo de dados normal, uma única operação de recv não abrange essa posição. Um recv retorna os dados normais antes da marca e um segundo recv é necessário para começar a ler dados após a marca.

Com SO_OOBINLINE habilitado:

  • FD_OOB mensagens não são postadas para dados OOB. Os dados do OOB são tratados como normais para fins do selecionar e funções de WSAAsyncSelect e indicados definindo o soquete em de leituras ou enviando uma mensagem de FD_READ respectivamente.
  • O aplicativo não pode chamar recv com o sinalizador MSG_OOB definido para ler o bloco de dados OOB. O código de erro WSAEINVAL é retornado.
  • O aplicativo pode chamar recv sem o conjunto de sinalizadores de MSG_OOB. Todos os dados OOB são entregues em sua ordem correta dentro do fluxo de dados normal. Os dados do OOB nunca são misturados com dados normais. Deve haver três solicitações de leitura para passar pelos dados do OOB. O primeiro retorna os dados normais antes do bloco de dados OOB, o segundo retorna os dados OOB, o terceiro retorna os dados normais após os dados do OOB. Em outras palavras, os limites do bloco de dados OOB são preservados.

A rotina deWSAAsyncSelect é particularmente adequada para lidar com a notificação da presença de dados fora da banda quando SO_OOBINLINE está desativado.

Dados OOB no TCP

Importante

A discussão a seguir sobre dados fora de banda (OOB), implementada usando dados urgentes TCP, segue o modelo usado na distribuição de software de Berkeley. Os usuários e implementadores devem estar cientes de que:

 

  • Há, no momento, duas interpretações conflitantes de RFC 793 (em que o conceito é introduzido).

  • A implementação de dados OOB no Berkeley Software Distribution (BSD) não está em conformidade com os Requisitos de Host especificados no RFC 1122.

    Especificamente, o ponteiro urgente TCP no BSD aponta para o byte após o byte de dados urgente e um ponteiro urgente TCP compatível com RFC aponta para o byte de dados urgente. Como resultado, se um aplicativo enviar dados urgentes de uma implementação compatível com BSD para uma implementação compatível com RFC 1122, o receptor lerá o byte de dados urgente incorreto (ele lê o byte localizado após o byte correto no fluxo de dados como byte de dados urgente).

    Para minimizar problemas de interoperabilidade, os gravadores de aplicativos são aconselhados a não usar dados OOB, a menos que isso seja necessário para interoperar com um serviço existente. Os fornecedores do Windows Sockets são instados a documentar a semântica OOB (BSD ou RFC 1122) que seu produto implementa.

A chegada de um segmento TCP com o conjunto de sinalizadores URG (para urgência) indica a existência de um único byte de dados OOB no fluxo de dados TCP. O bloco de dados OOB tem um byte de tamanho. O ponteiro urgente é um deslocamento positivo do número de sequência atual no cabeçalho TCP que indica o local do bloco de dados OOB (ambíguo, conforme observado no anterior). Ele pode, portanto, apontar para dados que ainda não foram recebidos.

Se SO_OOBINLINE estiver desabilitado (o padrão) quando o segmento TCP que contém o byte apontado pelo ponteiro urgente chegar, o bloco de dados OOB (um byte) será removido do fluxo de dados e armazenado em buffer. Se um segmento TCP subsequente chegar com o conjunto de sinalizadores urgente (e um novo ponteiro urgente), o byte OOB atualmente enfileirado poderá ser perdido à medida que for substituído pelo novo bloco de dados OOB (como ocorre na Distribuição de Software do Berkeley). No entanto, ele nunca é substituído no fluxo de dados.

Com SO_OOBINLINE habilitado, os dados urgentes permanecem no fluxo de dados. Como resultado, o bloco de dados OOB nunca é perdido quando um novo segmento TCP chega contendo dados urgentes. A marca de dados OOB existente é atualizada para a nova posição.

Nota

Quando a opção de soquete SO_OOBINLINE é definida, o IOCTL SIOCATMARK sempre retorna VERDADEIROe os dados OOB são retornados ao usuário como dados normais.