Condividi tramite


Windows Sockets: ordinamento dei byte

In questo articolo e nei due articoli correlati vengono illustrati diversi problemi che si presentano nella programmazione Windows Sockets. Questo articolo illustra l'ordinamento dei byte. Gli altri problemi sono trattati negli articoli: Windows Sockets: Blocking and Windows Sockets: Converting Strings.The other issues are covered in the articles: Windows Sockets: Blocking and Windows Sockets: Converting Strings.

Se si usa o si deriva dalla classe CAsyncSocket, sarà necessario gestire manualmente questi problemi. Se si usa o si deriva dalla classe CSocket, MFC li gestisce automaticamente.

ordine dei byte

A volte diverse architetture di computer archiviano i dati usando ordini di byte diversi. Ad esempio, i computer basati su Intel archiviano i dati nell'ordine inverso dei computer Macintosh (Motorola). L'ordine dei byte Intel, chiamato "little-Endian", è anche il contrario dell'ordine standard di rete "big-Endian". Nella tabella seguente vengono illustrati questi termini.

Ordinamento dei byte big-endian e little-endian

ordinamento dei byte Significato
Big-Endian Il byte più significativo è alla fine sinistra di una parola.
Little-Endian Il byte più significativo è alla fine destra di una parola.

In genere, non è necessario preoccuparsi della conversione degli ordini di byte per i dati inviati e ricevuti in rete, ma esistono situazioni in cui è necessario convertire gli ordini di byte.

Quando è necessario convertire gli ordini di byte

È necessario convertire gli ordini di byte nelle situazioni seguenti:

  • Si passano informazioni che devono essere interpretate dalla rete, anziché i dati inviati a un altro computer. Ad esempio, è possibile passare porte e indirizzi, che la rete deve comprendere.

  • L'applicazione server con cui si sta comunicando non è un'applicazione MFC e non si dispone del codice sorgente per tale applicazione. Viene chiamato per le conversioni degli ordini di byte se i due computer non condividono lo stesso ordinamento dei byte.

Quando non è necessario convertire gli ordini di byte

È possibile evitare il lavoro di conversione degli ordini di byte nelle situazioni seguenti:

  • I computer in entrambe le estremità possono accettare di non scambiare byte e entrambi i computer usano lo stesso ordine di byte.

  • Il server con cui si sta comunicando è un'applicazione MFC.

  • Si dispone di codice sorgente per il server con cui si sta comunicando, quindi è possibile indicare in modo esplicito se è necessario convertire o meno gli ordini di byte.

  • È possibile convertire il server in MFC. Questa operazione è abbastanza semplice e il risultato è in genere più piccolo e più veloce.

Lavorare con CAsyncSocket, è necessario gestire manualmente le conversioni degli ordini di byte necessarie. Windows Sockets standardizza il modello di byte "big-Endian" e fornisce funzioni per la conversione tra questo ordine e altri. CArchive, tuttavia, che si usa con CSocket, usa l'ordine opposto ("little-Endian"), ma CArchive si occupa dei dettagli delle conversioni degli ordini di byte. Usando questo ordinamento standard nelle applicazioni o usando le funzioni di conversione dei byte order di Windows Sockets, è possibile rendere il codice più portabile.

Il caso ideale per l'uso dei socket MFC è quando si scrivono entrambe le estremità della comunicazione: usando MFC a entrambe le estremità. Se si scrive un'applicazione che comunicherà con applicazioni non MFC, ad esempio un server FTP, sarà probabilmente necessario gestire lo scambio di byte prima di passare i dati all'oggetto archivio, usando le routine di conversione di Windows Sockets ntohs, ntohl, htons e htonl. Un esempio di queste funzioni usate per la comunicazione con un'applicazione non MFC viene visualizzata più avanti in questo articolo.

Nota

Quando l'altra estremità della comunicazione non è un'applicazione MFC, è inoltre necessario evitare lo streaming di oggetti C++ derivati dall'archivio CObject perché il ricevitore non sarà in grado di gestirli. Vedere la nota in Windows Sockets: Using Sockets with Archives (Uso di socket con archivi).

Per altre informazioni sugli ordini di byte, vedere la specifica di Windows Sockets, disponibile in Windows SDK.

Esempio di conversione in ordine di byte

Nell'esempio seguente viene illustrata una funzione di serializzazione per un CSocket oggetto che usa un archivio. Illustra anche l'uso delle funzioni di conversione degli ordini di byte nell'API Windows Sockets.

Questo esempio presenta uno scenario in cui si sta scrivendo un client che comunica con un'applicazione server non MFC per cui non si ha accesso al codice sorgente. In questo scenario, è necessario presupporre che il server non MFC usi l'ordine dei byte di rete standard. Al contrario, l'applicazione client MFC usa un CArchive oggetto con un CSocket oggetto e CArchive usa l'ordine dei byte "little-Endian", l'opposto dello standard di rete.

Si supponga che il server non MFC con cui si prevede di comunicare abbia un protocollo stabilito per un pacchetto di messaggi simile al seguente:

struct Message
{
   long MagicNumber;
   unsigned short Command;
   short Param1;
   long Param2;
};

In termini MFC, questo sarebbe espresso come segue:

struct Message
{
   long m_lMagicNumber;
   short m_nCommand;
   short m_nParam1;
   long m_lParam2;

   void Serialize(CArchive &ar);
};

In C++, un struct oggetto è essenzialmente la stessa cosa di una classe. La Message struttura può avere funzioni membro, ad esempio la Serialize funzione membro dichiarata in precedenza. La Serialize funzione membro potrebbe essere simile alla seguente:

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);
   }
}

In questo esempio vengono chiamate conversioni di byte-order di dati perché esiste una chiara mancata corrispondenza tra l'ordinamento dei byte dell'applicazione server non MFC su un'estremità e l'oggetto CArchive usato nell'applicazione client MFC nell'altra. L'esempio illustra diverse funzioni di conversione degli ordini di byte fornite da Windows Sockets. Nella tabella seguente vengono descritte queste funzioni.

Funzioni di conversione dei byte order di Windows Sockets

Funzione Scopo
ntohs Convertire una quantità a 16 bit dall'ordine dei byte di rete all'ordine dei byte host (big-Endian in little-Endian).
ntohl Convertire una quantità a 32 bit dall'ordine di byte di rete all'ordine dei byte host (big-Endian in little-Endian).
Htons Convertire una quantità a 16 bit dall'ordine dei byte host all'ordine dei byte di rete (little-Endian in big-Endian).
Htonl Convertire una quantità a 32 bit da un ordine di byte host a un ordine di byte di rete (little-Endian in big-Endian).

Un altro punto di questo esempio è che quando l'applicazione socket sull'altra estremità della comunicazione è un'applicazione non MFC, è necessario evitare di eseguire operazioni simili alle seguenti:

ar << pMsg;

dove pMsg è un puntatore a un oggetto C++ derivato dalla classe CObject. In questo modo verranno inviate informazioni MFC aggiuntive associate agli oggetti e il server non lo comprenderà, come se fosse un'applicazione MFC.

Per altre informazioni, vedere:

Vedi anche

Windows Sockets in MFC