Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Este artigo e dois artigos complementares explicam vários problemas na programação do Windows Sockets. Este artigo aborda a ordem de bytes. As outras questões são abordadas nos artigos: Windows Sockets: Blocking e Windows Sockets: Converting Strings.
Se você usar ou derivar da classe CAsyncSocket, precisará gerenciar esses problemas por conta própria. Se você usa ou deriva da classe CSocket, a MFC os gerencia para você.
Ordenação de bytes
Diferentes arquiteturas de máquina às vezes armazenam dados usando ordens de bytes diferentes. Por exemplo, as máquinas baseadas em Intel armazenam dados na ordem inversa das máquinas Macintosh (Motorola). A ordem de bytes da Intel, chamada de "little-Endian", também é o inverso da ordem padrão de rede "big-Endian". A tabela a seguir explica esses termos.
Ordenação de bytes grandes e Little-Endian
| Ordenação de bytes | Significado |
|---|---|
| Big-Endian | O byte mais significativo está na extremidade esquerda de uma palavra. |
| Little-Endian | O byte mais significativo está na extremidade direita de uma palavra. |
Normalmente, você não precisa se preocupar com a conversão de ordem de bytes para dados que você envia e recebe pela rede, mas há situações em que você deve converter ordens de bytes.
Quando você deve converter ordens de bytes
Você precisa converter ordens de bytes nas seguintes situações:
Você está passando informações que precisam ser interpretadas pela rede, em oposição aos dados que você está enviando para outra máquina. Por exemplo, você pode passar portas e endereços, que a rede deve entender.
O aplicativo de servidor com o qual você está se comunicando não é um aplicativo MFC (e você não tem código-fonte para ele). Isso exige conversões de ordem de bytes se as duas máquinas não compartilharem a mesma ordem de bytes.
Quando você não precisa converter ordens de bytes
Você pode evitar o trabalho de conversão de ordens de bytes nas seguintes situações:
As máquinas em ambas as extremidades podem concordar em não trocar bytes, e ambas as máquinas usam a mesma ordem de bytes.
O servidor com o qual você está se comunicando é um aplicativo MFC.
Você tem o código-fonte do servidor com o qual está se comunicando, assim pode determinar claramente se precisa converter a ordem dos bytes ou não.
Você pode portar o servidor para MFC. Isso é bastante fácil de fazer, e o resultado geralmente é um código menor e mais rápido.
Trabalhando com CAsyncSocket, você mesmo deve gerenciar todas as conversões de ordem de bytes necessárias. O Windows Sockets padroniza o modelo de ordem de bytes "big-Endian" e fornece funções para converter entre esta ordem e outras. O CArchive, no entanto, que utilizas com o CSocket, emprega a ordem oposta ("little-Endian"), mas CArchive cuida dos detalhes das conversões de ordem de bytes para ti. Usando esta ordenação padrão nos seus aplicativos, ou utilizando as funções de conversão de ordem de bytes do Windows Sockets, poderá tornar o seu código mais portátil.
O caso ideal para usar soquetes MFC é quando você está escrevendo ambas as extremidades da comunicação: usando MFC em ambas as extremidades. Se você estiver escrevendo um aplicativo que se comunicará com aplicativos não-MFC, como um servidor FTP, provavelmente precisará gerenciar a troca de bytes antes de passar dados para o objeto de arquivamento, usando as rotinas de conversão do Windows Sockets ntohs, ntohl, htons e htonl. Um exemplo dessas funções usadas na comunicação com um aplicativo não-MFC aparece mais adiante neste artigo.
Observação
Quando a outra extremidade da comunicação não é uma aplicação MFC, deve também evitar o streaming de objetos C++ derivados de CObject para o seu arquivo, porque o destinatário não conseguiria processá-los. Consulte a nota em Windows Sockets: Using Sockets with Archives.
Para obter mais informações sobre ordens de bytes, consulte a especificação Windows Sockets, disponível no SDK do Windows.
Um exemplo de conversão Byte-Order
O exemplo a seguir mostra uma função de serialização para um CSocket objeto que usa um arquivo. O texto também ilustra o uso das funções de conversão de ordem de bytes na API Windows Sockets.
Este exemplo apresenta um cenário no qual você está escrevendo um cliente que se comunica com um aplicativo de servidor não-MFC para o qual você não tem acesso ao código-fonte. Nesse cenário, você deve assumir que o servidor não-MFC usa a ordem de bytes de rede padrão. Em contraste com isso, a sua aplicação cliente MFC utiliza um CArchive objeto em conjunto com um CSocket objeto, e o CArchive utiliza a ordem de bytes "little-Endian", o oposto do padrão de rede.
Suponha que o servidor não-MFC com o qual você planeja se comunicar tenha um protocolo estabelecido para um pacote de mensagens como o seguinte:
struct Message
{
long MagicNumber;
unsigned short Command;
short Param1;
long Param2;
};
Em termos de MFC, isto seria expresso da seguinte forma:
struct Message
{
long m_lMagicNumber;
short m_nCommand;
short m_nParam1;
long m_lParam2;
void Serialize(CArchive &ar);
};
Em C++, a struct é essencialmente a mesma coisa que uma classe. A Message estrutura pode ter funções de membro, como a função de membro declarada Serialize acima. A Serialize função de membro pode ter esta aparência:
void Message::Serialize(CArchive &ar)
{
if (ar.IsStoring())
{
ar << (DWORD)htonl(m_lMagicNumber);
ar << (WORD)htons(m_nCommand);
ar << (WORD)htons(m_nParam1);
ar << (DWORD)htonl(m_lParam2);
}
else
{
WORD w;
DWORD dw;
ar >> dw;
m_lMagicNumber = ntohl((long)dw);
ar >> w;
m_nCommand = ntohs((short)w);
ar >> w;
m_nParam1 = ntohs((short)w);
ar >> dw;
m_lParam2 = ntohl((long)dw);
}
}
Este exemplo pede conversões de dados por ordem de bytes porque há uma clara incompatibilidade entre a ordem de bytes do aplicativo de servidor não-MFC em uma extremidade e o CArchive usado em seu aplicativo cliente MFC na outra extremidade. O exemplo ilustra várias das funções de conversão de ordem de bytes que o Windows Sockets fornece. A tabela a seguir descreve essas funções.
Funções de Conversão de Windows Sockets Byte-Order
| Função | Propósito |
|---|---|
| NTOHS | Converta uma quantidade de 16 bits da ordem de bytes da rede para a ordem de bytes do host (big-Endian para little-Endian). |
| Ntohl | Converter uma quantidade de 32 bits da ordem de bytes de rede para a ordem de bytes do host (de big-Endian para little-Endian). |
| Htons | Converta uma quantidade de 16 bits da ordem de bytes do host para a ordem de bytes da rede (little-Endian para big-Endian). |
| Htonl | Converta um valor de 32 bits da ordem de bytes do host para a ordem de bytes da rede (de little-endian para big-endian). |
Outro ponto deste exemplo é que quando o aplicativo de soquete na outra extremidade da comunicação é um aplicativo não-MFC, você deve evitar fazer algo como o seguinte:
ar << pMsg;
onde pMsg é um ponteiro para um objeto C++ derivado da classe CObject. Isso enviará informações MFC extras associadas a objetos e o servidor não as entenderá, como faria se fosse um aplicativo MFC.
Para obter mais informações, consulte: