Partilhar via


Envio e Recebimento de Dados PGM

Enviar e receber dados PGM é semelhante a enviar ou receber dados em qualquer soquete. Há considerações específicas do PGM, descritas nos parágrafos seguintes.

Envio de dados PGM

Depois que uma sessão de remetente PGM é criada, os dados são enviados usando as várias funções de envio do Windows Sockets: send, sendto, WSASende WSASendTo. Como os identificadores do Windows Sockets são identificadores do sistema de arquivos, outras funções, como WriteFile e funções CRT, também podem transmitir dados. O trecho de código a seguir ilustra uma operação de remetente PGM:

LONG        error;
    //:
error = send (s, pSendBuffer, SendLength, 0);
if (error == SOCKET_ERROR)
{
    fprintf (stderr, "send() failed: Error = %d\n",
             WSAGetLastError());
}

Ao usar o modo de mensagem (SOCK_RDM), cada chamada para uma função de envio resulta em uma mensagem discreta, o que às vezes não é desejável; Um aplicativo pode querer enviar uma mensagem de 2 megabytes com várias chamadas para enviar. Nessas circunstâncias, o remetente pode definir a opção de soquete RM_SET_MESSAGE_BOUNDARY para indicar o tamanho da mensagem que se segue.

Se a janela de envio estiver cheia, um novo envio do aplicativo não será aceito até que a janela tenha sido avançada. A tentativa de enviar em um soquete sem bloqueio falha com WSAEWOULDBLOCK; Um soquete de bloqueio simplesmente bloqueia até que a janela avance até o ponto onde os dados solicitados podem ser armazenados em buffer e enviados. Em E/S sobrepostas, a operação não é concluída até que a janela avance o suficiente para acomodar os novos dados.

Recebimento de dados PGM

Uma vez que uma sessão de recetor PGM é criada, os dados são recebidos usando as várias funções de receção do Windows Sockets: recv, recvfrom, WSARecve WSARecvFrom. Como os identificadores do Windows Sockets também são identificadores de arquivo, as funções ReadFile e CRT também podem ser usadas para receber dados de sessão PGM. O transporte encaminha os dados para o recetor à medida que chegam, desde que os dados estejam em sequência. O transporte garante que os dados devolvidos são contíguos e isentos de duplicados. O trecho de código a seguir ilustra uma operação de recebimento PGM:

LONG        BytesRead;
    //:
BytesRead = recv (sockR, pTestBuffer, MaxBufferSize, 0);
if (BytesRead == 0)
{
    fprintf(stdout, "Session was terminated\n");
}
else if (BytesRead == SOCKET_ERROR)
{
    fprintf(stderr, "recv() failed: Error = %d\n",
            WSAGetLastError());
}

Ao utilizar o modo de mensagem (SOCK_RDM), o transporte indica quando uma mensagem parcial é recebida, seja através do erro WSAEMSGSIZE ou ao definir o indicador MSG_PARTIAL ao retornar das funções WSARecv e WSARecvFrom. Quando o último fragmento da mensagem completa é retornado ao cliente, o erro ou sinalizador não é indicado.

Quando a sessão é encerrada normalmente, a operação de recebimento falha com o WSAEDISCON. Quando ocorre perda de dados no transporte, o PGM armazena temporariamente em buffer os pacotes fora de sequência e tenta recuperar os dados perdidos. Se a perda de dados for irrecuperável, a operação de recebimento falhará com WSAECONNRESET, e a sessão será encerrada. A sessão pode ser redefinida devido a uma variedade de condições, incluindo as seguintes:

  • O recetor ou a velocidade da conexão de entrada é demasiado lenta para acompanhar a taxa de dados de entrada.
  • Ocorre perda excessiva de dados, possivelmente devido a condições transitórias da rede, como problemas de roteamento, instabilidade da rede e assim por diante.
  • Ocorre um erro irrecuperável no remetente.
  • A utilização excessiva de recursos ocorre no computador local, como exceder o armazenamento de buffer interno máximo permitido ou encontrar uma condição de falta de recursos.
  • Ocorre um erro de verificação de consistência de dados.
  • A falha de um componente PGM depende de outros, como TCP/IP ou Windows Sockets.

Tanto o primeiro quanto o segundo itens na lista acima podem resultar no recetor executando buffering excessivo antes de ficar sem recursos, ou antes de finalmente ir além da janela do remetente.

Encerrando uma sessão PGM

O emissor ou recetor PGM pode parar de enviar ou receber dados chamando closesocket. O receptor deve chamar closesocket nos sockets de escuta e recepção para evitar fugas de manuseamento. Chamar a função de desligamento no remetente antes de chamar closesocket garante que todos os dados sejam enviados e garante que os dados de correção sejam mantidos até que a janela de envio avance além da última sequência de dados, mesmo que o próprio aplicativo seja encerrado.