Classe CSocket
Deriva de CAsyncSocket
, herda seu encapsulamento da API do Windows Sockets e representa um nível mais alto de abstração do que o de um objeto CAsyncSocket
.
Sintaxe
class CSocket : public CAsyncSocket
Membros
Construtores públicos
Nome | Descrição |
---|---|
CSocket::CSocket |
Constrói um objeto CSocket . |
Métodos públicos
Nome | Descrição |
---|---|
CSocket::Attach |
Anexa um identificador SOCKET a um objeto CSocket . |
CSocket::CancelBlockingCall |
Cancela uma chamada de bloqueio que esteja em andamento no momento. |
CSocket::Create |
Cria um soquete. |
CSocket::FromHandle |
Retorna um ponteiro para um objeto CSocket , dado um identificador de SOCKET . |
CSocket::IsBlocking |
Determina se uma chamada de bloqueio está em andamento. |
Métodos protegidos
Nome | Descrição |
---|---|
CSocket::OnMessagePending |
Chamado para processar mensagens pendentes enquanto aguarda a conclusão de uma chamada de bloqueio. |
Comentários
CSocket
trabalha com as classes CSocketFile
e CArchive
para gerenciar o envio e o recebimento de dados.
Um objeto CSocket
também fornece bloqueio, o que é essencial para a operação síncrona de CArchive
. Funções de bloqueio, como Receive
, Send
, ReceiveFrom
, SendTo
e Accept
(todas herdadas de CAsyncSocket
), não retornam um erro WSAEWOULDBLOCK
em CSocket
. Em vez disso, essas funções esperam até que a operação seja concluída. Além disso, a chamada original terminará com o erro WSAEINTR se CancelBlockingCall
for chamado enquanto uma dessas funções estiver bloqueando.
Para usar um objeto CSocket
, chame o construtor e, em seguida, chame Create
para criar o identificador SOCKET
subjacente (tipo SOCKET
). Os parâmetros padrão de Create
criam um soquete de fluxo, mas se você não estiver usando o soquete com um objeto CArchive
, poderá especificar um parâmetro para criar um soquete de datagram ou associar a uma porta específica para criar um soquete de servidor. Conecte-se a um soquete do cliente usando Connect
no lado do cliente e Accept
no lado do servidor. Em seguida, crie um objeto CSocketFile
e associe-o ao objeto CSocket
no construtor CSocketFile
. Então, crie um objeto CArchive
para enviar e outro para receber dados (conforme necessário) e associe-os ao objeto CSocketFile
no construtor CArchive
. Quando as comunicações forem concluídas, destrua os objetos CArchive
, CSocketFile
e CSocket
. O tipo de dados SOCKET
é descrito no artigo Windows Sockets: Segundo plano.
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
}
}
Observação
Ao usar soquetes MFC em threads secundários em um aplicativo MFC vinculado estaticamente, você deve chamar AfxSocketInit
em cada thread que usa soquetes para inicializar as bibliotecas de soquete. Por padrão, AfxSocketInit
é chamado somente no thread primário.
Para obter mais informações, consulte Soquetes do Windows no MFC, Soquetes do Windows: usando soquetes com arquivos, Soquetes do Windows: como os soquetes com arquivos funcionam, Soquetes do Windows: sequência de operações, Soquetes do Windows: exemplo de soquetes usando arquivos.
Hierarquia de herança
CSocket
Requisitos
Cabeçalho: afxsock.h
CSocket::Attach
Chame essa função membro para anexar o identificador hSocket
a um objeto CSocket
.
BOOL Attach(SOCKET hSocket);
Parâmetros
hSocket
Contém um identificador de um soquete.
Valor de retorno
Diferente de zero se a função for bem-sucedida.
Comentários
O identificador SOCKET
é armazenado no membro de dados do objeto m_hSocket
.
Para obter mais informações, consulte Soquetes do Windows: usando soquetes com arquivos.
Exemplo
class CSockThread : public CWinThread
{
public:
SOCKET m_hConnected;
protected:
CChatSocket m_sConnected;
// remainder of class declaration omitted.
BOOL CSockThread::InitInstance()
{
// Attach the socket object to the socket handle
// in the context of this thread.
m_sConnected.Attach(m_hConnected);
m_hConnected = NULL;
return TRUE;
}
// This listening socket has been constructed
// in the primary thread.
void CListeningSocket::OnAccept(int nErrorCode)
{
UNREFERENCED_PARAMETER(nErrorCode);
// This CSocket object is used just temporarily
// to accept the incoming connection.
CSocket sConnected;
Accept(sConnected);
// Start the other thread.
CSockThread *pSockThread = (CSockThread*)AfxBeginThread(
RUNTIME_CLASS(CSockThread), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
if (NULL != pSockThread)
{
// Detach the newly accepted socket and save
// the SOCKET handle in our new thread object.
// After detaching it, it should no longer be
// used in the context of this thread.
pSockThread->m_hConnected = sConnected.Detach();
pSockThread->ResumeThread();
}
}
CSocket::CancelBlockingCall
Chame essa função membro para cancelar uma chamada de bloqueio atualmente em andamento.
void CancelBlockingCall();
Comentários
Essa função cancela qualquer operação de bloqueio pendente para este soquete. A chamada de bloqueio original será encerrada assim que possível com o erro WSAEINTR
.
No caso de uma operação de bloqueio Connect
, a implementação do Windows Sockets encerrará a chamada de bloqueio o mais rápido possível, mas pode não ser possível que os recursos do soquete sejam liberados até que a conexão seja concluída (e depois seja redefinida) ou atinja o tempo limite. Isso provavelmente será perceptível somente se o aplicativo tentar abrir imediatamente um novo soquete (se nenhum soquete estiver disponível) ou se conectar ao mesmo par.
Cancelar qualquer operação diferente de Accept
pode deixar o soquete em um estado indeterminado. Se um aplicativo cancelar uma operação de bloqueio em um soquete, a única operação que o aplicativo pode depender de poder executar no soquete é uma chamada para Close
, embora outras operações possam funcionar em algumas implementações do Windows Sockets. Se desejar portabilidade máxima para seu aplicativo, você deve ter cuidado para não depender da execução de operações após um cancelamento.
Para obter mais informações, consulte Soquetes do Windows: usando soquetes com arquivos.
CSocket::Create
Chame a função de membro Create
depois de construir um objeto de soquete para criar o soquete do Windows e anexá-lo.
BOOL Create(
UINT nSocketPort = 0,
int nSocketType = SOCK_STREAM,
LPCTSTR lpszSocketAddress = NULL);
Parâmetros
nSocketPort
Uma porta específica a ser usada com o soquete ou zero se você quiser que o MFC selecione uma porta.
nSocketType
SOCK_STREAM
ou SOCK_DGRAM
.
lpszSocketAddress
Um ponteiro para uma cadeia de caracteres que contém o endereço de rede do soquete conectado, um número separado por pontos, como "128.56.22.8". Passar a cadeia de caracteres NULL para esse parâmetro indica que a instância CSocket
deve escutar a atividade do cliente em todas os interfaces de rede.
Valor de retorno
Diferente de zero se a função for bem-sucedida; caso contrário, 0 e um código de erro específico pode ser recuperado chamando GetLastError
.
Comentários
Create
em seguida chama Bind
para associar o soquete ao endereço especificado. Há suporte para os seguintes tipos de soquete:
SOCK_STREAM
Fornece fluxos de bytes baseados em conexão sequenciados, confiáveis e bidirecionais. Usa o protocolo TCP para a família de endereços na Internet.SOCK_DGRAM
Possui suporte para datagramas, que são pacotes sem conexão e não confiáveis de um comprimento máximo fixo (normalmente pequeno). Usa o UDP (User Datagram Protocol) para a família de endereços na Internet. Para usar essa opção, você não deve usar o soquete com um objetoCArchive
.Observação
A função membro
Accept
faz uma referência a um novo objetoCSocket
vazio como seu parâmetro. Você deve construir esse objeto antes de chamarAccept
. Tenha em mente que, se esse objeto de soquete ficar fora do escopo, a conexão será fechada. Não chameCreate
para esse novo objeto de soquete.
Para obter mais informações sobre soquetes de fluxo e datagrama, consulte os artigos Windows Sockets: Segundo plano, Windows Sockets: Endereços de portas e soquetes e Windows Sockets: usando soquetes com arquivos.
CSocket::CSocket
Constrói um objeto CSocket
.
CSocket();
Comentários
Após a construção, você deve chamar a função membro Create
.
Para obter mais informações, consulte Soquetes do Windows: usando soquetes com arquivos.
CSocket::FromHandle
Um ponteiro para um objeto CSocket
.
static CSocket* PASCAL FromHandle(SOCKET hSocket);
Parâmetros
hSocket
Contém um identificador de um soquete.
Valor de retorno
Um ponteiro para um objeto CSocket
, ou NULL
se não houver nenhum objeto CSocket
anexado a hSocket
.
Comentários
Quando determinado um identificador SOCKET
, se um objeto CSocket
não estiver anexado ao identificador, a função membro retornará NULL
e não criará um objeto temporário.
Para obter mais informações, consulte Soquetes do Windows: usando soquetes com arquivos.
CSocket::IsBlocking
Chame essa função membro para determinar se uma chamada de bloqueio está em andamento.
BOOL IsBlocking();
Valor de retorno
Diferente de zero se o soquete estiver bloqueando; caso contrário, zero.
Comentários
Para obter mais informações, consulte Soquetes do Windows: usando soquetes com arquivos.
CSocket::OnMessagePending
Substitua essa função membro para procurar mensagens específicas do Windows e responda a elas em seu soquete.
virtual BOOL OnMessagePending();
Valor de retorno
Diferente de zero se a mensagem tiver sido tratada; caso contrário, zero.
Comentários
Essa é uma substituição avançada.
A estrutura chama OnMessagePending
enquanto o soquete está enviando mensagens do Windows para lhe dar a oportunidade de lidar com mensagens de interesse para seu aplicativo. Para obter exemplos de como você pode usar OnMessagePending
, consulte o artigo Soquetes do Windows: Derivando de classes de soquete.
Para obter mais informações, consulte Soquetes do Windows: usando soquetes com arquivos.
Confira também
Classe CAsyncSocket
Gráfico da hierarquia
Classe CAsyncSocket
Classe CSocketFile