Compartilhar via


Classe CSocketFile

Um objeto CFile usado para enviar e receber dados em uma rede por meio do Windows Sockets.

Sintaxe

class CSocketFile : public CFile

Membros

Construtores públicos

Nome Descrição
CSocketFile::CSocketFile Constrói um objeto CSocketFile.

Comentários

Você pode anexar o objeto CSocketFile a um objeto CSocket para essa finalidade. Você também pode, e normalmente irá, anexar o objeto CSocketFile a um objeto CArchive para simplificar o envio e o recebimento de dados usando a serialização MFC.

Para serializar (enviar) dados, insira-os no arquivo morto, que chama funções membro CSocketFile para gravar dados no objeto CSocket. Para desserializar (receber) dados, extraia do arquivo morto. Isso faz com que o arquivo morto chame funções membro CSocketFile para ler dados do objeto CSocket.

Dica

Além de usar CSocketFile como descrito aqui, você pode usá-lo como um objeto de arquivo autônomo, exatamente como é possível com CFile, sua classe base. Você também pode usar CSocketFile com qualquer função de serialização MFC baseada em arquivo morto. Como CSocketFile não dá suporte a todas as funcionalidades de CFile, algumas funções de serialização MFC padrão não são compatíveis com CSocketFile. Isso é particularmente verdadeiro para a classe CEditView. Você não deve tentar serializar dados CEditView por meio de um objeto CArchive anexado a um objeto CSocketFile usando CEditView::SerializeRaw; em vez disso, use CEditView::Serialize. A função SerializeRaw espera que o objeto de arquivo tenha funções, como Seek, que CSocketFile não têm.

Quando você usa CArchive com CSocketFile e CSocket, pode encontrar uma situação em que CSocket::Receive insere um loop (por PumpMessages(FD_READ)) aguardando a quantidade solicitada de bytes. Isso ocorre porque os soquetes do Windows permitem apenas uma chamada recv por notificação FD_READ, mas CSocketFile e CSocket permitem várias chamadas recv por FD_READ. Se você receber um FD_READ quando não houver dados para ler, o aplicativo ficará travado. Se você nunca receber outro FD_READ, o aplicativo deixará de se comunicar pelo soquete.

Você pode resolver esse problema da seguinte maneira. No método OnReceive da classe de soquete, chame CAsyncSocket::IOCtl(FIONREAD, ...) antes de chamar o método Serialize da classe de mensagem quando os dados esperados a serem lidos do soquete excederem o tamanho de um pacote TCP (unidade de transmissão máxima do meio de rede, em geral, pelo menos 1096 bytes). Se o tamanho dos dados disponíveis for menor do que o necessário, aguarde até que todos os dados sejam recebidos e, somente em seguida, inicie a operação de leitura.

No exemplo a seguir, m_dwExpected é o número aproximado de bytes que o usuário espera receber. Supõe-se que você o declare em outro lugar em seu código.

void CChatSocket::OnReceive(int nErrorCode)
{
   CSocket::OnReceive(nErrorCode);

   DWORD dwReceived;

   if (IOCtl(FIONREAD, &dwReceived))
   {
      if (dwReceived >= m_dwExpected) // Process only if you have enough data
         m_pDoc->ProcessPendingRead();
   }
   else
   {
      // Error handling here
   }
}

Para obter mais informações, consulte Windows Sockets no MFC, Windows Sockets: Usar Soquetes com Arquivos Mortos, bem como API do Windows Sockets 2.

Hierarquia de herança

CObject

CFile

CSocketFile

Requisitos

Cabeçalho: afxsock.h

CSocketFile::CSocketFile

Constrói um objeto CSocketFile.

explicit CSocketFile(
    CSocket* pSocket,
    BOOL bArchiveCompatible = TRUE);

Parâmetros

pSocket
O soquete a ser anexado ao objeto CSocketFile.

bArchiveCompatible
Especifica se o objeto de arquivo é para uso com um objeto CArchive. Passe FALSE somente se você quiser usar o objeto CSocketFile de maneira autônoma, como faria com um objeto CFile autônomo, com determinadas limitações. Esse sinalizador altera a forma como o objeto CArchive anexado ao objeto CSocketFile gerencia seu buffer para leitura.

Comentários

O destruidor do objeto se desassocia do objeto de soquete quando o objeto sai do escopo ou é excluído.

Observação

Um CSocketFile também pode ser usado como um arquivo (limitado) sem um objeto CArchive. Por padrão, o parâmetro bArchiveCompatible do construtor CSocketFile é TRUE. Isso especifica que o objeto de arquivo é usado com um arquivo morto. Para usar o objeto de arquivo sem um arquivo morto, passe FALSE no parâmetro bArchiveCompatible.

Em seu modo "compatível com arquivo morto", um objeto CSocketFile fornece melhor desempenho e reduz o perigo de um "deadlock". Um deadlock ocorre quando os soquetes de envio e recebimento estão esperando um pelo outro ou por um recurso comum. Essa situação poderá ocorrer se o objeto CArchive funcionou com o CSocketFile da maneira como funciona com um objeto CFile. Com CFile, o arquivo morto pode presumir que, se ele receber menos bytes do que o solicitado, o fim do arquivo foi atingido.

Com CSocketFile, no entanto, os dados são baseados em mensagens; o buffer pode conter várias mensagens, portanto, receber menos do que o número de bytes solicitados não implica o fim do arquivo. O aplicativo não é bloqueado nesse caso como pode acontecer com CFile, e pode continuar lendo mensagens do buffer até que o buffer esteja vazio. A função CArchive::IsBufferEmpty é útil para monitorar o estado do buffer do arquivo morto nesse caso.

Para obter mais informações sobre o uso de CSocketFile, consulte os artigos Windows Sockets: Usar soquetes com arquivos mortos e Windows Sockets: exemplo de soquetes usando arquivos mortos.

Confira também

Classe CFile
Gráfico da hierarquia
Classe CAsyncSocket
Classe CSocket