Compartilhar via


Enviando e recebendo dados PGM

Enviar e receber dados PGM é semelhante ao envio ou recebimento de dados em qualquer soquete. Há considerações específicas ao PGM, descritas nos parágrafos a seguir.

Enviando 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, WSASend e WSASendTo. Como os identificadores do Windows Sockets são identificadores do sistema de arquivos, outras funções, como WriteFile e CRT, também podem transmitir dados. O snippet 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 a seguir.

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

Recebendo dados PGM

Depois que uma sessão de receptor PGM é criada, os dados são recebidos usando as várias funções de recebimento do Windows Sockets: recv, recvfrom, WSARecv e 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 até o receptor à medida que eles chegam, desde que os dados estão em sequência. O transporte garante que os dados retornados sejam contíguos e livres de duplicatas. O snippet de código a seguir ilustra uma operação de recebimento de 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 usar o modo de mensagem (SOCK_RDM), o transporte indica quando uma mensagem parcial é recebida, seja com o erro WSAEMSGSIZE ou definindo o sinalizador MSG_PARTIAL no retorno 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 WSAEDISCON. Quando a perda de dados ocorre 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 receptor ou a taxa de conexão de entrada é muito lenta para acompanhar a taxa de dados de entrada.
  • Ocorre perda excessiva de dados, possivelmente devido a condições transitórias de rede, como problemas de roteamento, instabilidade de 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 recursos insuficientes.
  • Ocorre um erro de consistência de dados marcar.
  • A falha em um PGM de componente depende, como TCP/IP ou Windows Sockets.

Tanto o primeiro quanto o segundo itens na lista acima podem resultar na execução excessiva de buffer do receptor antes de ficar sem recursos ou antes de, por fim, ir além da janela do remetente.

Encerrando uma sessão PGM

O remetente ou receptor PGM pode parar de enviar ou receber dados chamando closesocket. O receptor deve chamar closesocket nos soquetes de escuta e recebimento para evitar vazamentos de identificador. Chamar o desligamento no remetente antes de chamar closesocket garante que todos os dados sejam enviados e garante que os dados de reparo sejam mantidos até que a janela de envio passe da última sequência de dados, mesmo que o próprio aplicativo seja encerrado.