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
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