Windows Sockets: Orden de bytesWindows Sockets: Byte Ordering

En este artículo y dos artículos complementarios se explican varios problemas en la programación de Windows Sockets.This article and two companion articles explain several issues in Windows Sockets programming. En este artículo se describe el orden de los bytes.This article covers byte ordering. Los demás problemas se describen en los artículos: Windows Sockets: bloqueo y Windows Sockets: convertir cadenas.The other issues are covered in the articles: Windows Sockets: Blocking and Windows Sockets: Converting Strings.

Si usa o deriva de la clase CAsyncSocket, tendrá que administrar estos problemas por sí mismo.If you use or derive from class CAsyncSocket, you will need to manage these issues yourself. Si usa o deriva de la clase CSocket, MFC los administra automáticamente.If you use or derive from class CSocket, MFC manages them for you.

ordenación de bytesByte Ordering

A veces, las distintas arquitecturas de máquina almacenan datos mediante diferentes pedidos de bytes.Different machine architectures sometimes store data using different byte orders. Por ejemplo, los equipos basados en Intel almacenan los datos en el orden inverso de los equipos Macintosh (Motorola).For example, Intel-based machines store data in the reverse order of Macintosh (Motorola) machines. El orden de bytes de Intel, llamado "Little endian", también es el inverso del orden "Big-endian" estándar de red.The Intel byte order, called "little-Endian," is also the reverse of the network standard "big-Endian" order. En la tabla siguiente se explican estos términos.The following table explains these terms.

Orden de bytes de Big y Little-EndianBig- and Little-Endian Byte Ordering

Ordenación de bytesByte ordering SignificadoMeaning
Big-EndianBig-Endian El byte más significativo está en el extremo izquierdo de una palabra.The most significant byte is on the left end of a word.
Little-EndianLittle-Endian El byte más significativo está en el extremo derecho de una palabra.The most significant byte is on the right end of a word.

Normalmente, no tiene que preocuparse de la conversión de orden de bytes para los datos que envía y recibe a través de la red, pero hay situaciones en las que debe convertir los pedidos de bytes.Typically, you do not have to worry about byte-order conversion for data that you send and receive over the network, but there are situations in which you must convert byte orders.

Cuándo se deben convertir los pedidos de bytesWhen You Must Convert Byte Orders

Debe convertir los pedidos de bytes en las siguientes situaciones:You need to convert byte orders in the following situations:

  • Está pasando información que debe interpretar la red, en lugar de los datos que envía a otra máquina.You are passing information that needs to be interpreted by the network, as opposed to the data you are sending to another machine. Por ejemplo, puede pasar los puertos y las direcciones que la red debe comprender.For example, you might pass ports and addresses, which the network must understand.

  • La aplicación de servidor con la que se está comunicando no es una aplicación MFC (y no tiene código fuente para ella).The server application with which you are communicating is not an MFC application (and you do not have source code for it). Este método llama a las conversiones de orden de bytes si las dos máquinas no comparten la misma ordenación de bytes.This calls for byte order conversions if the two machines do not share the same byte ordering.

Cuando no es necesario convertir los pedidos de bytesWhen You Do Not Have to Convert Byte Orders

Puede evitar el trabajo de conversión de pedidos de bytes en las siguientes situaciones:You can avoid the work of converting byte orders in the following situations:

  • Los equipos de ambos extremos pueden estar de acuerdo en no intercambiar bytes y ambos equipos usan el mismo orden de bytes.The machines on both ends can agree not to swap bytes, and both machines use the same byte order.

  • El servidor con el que se está comunicando es una aplicación MFC.The server you are communicating with is an MFC application.

  • Tiene código fuente para el servidor con el que se está comunicando, por lo que puede indicar explícitamente si debe convertir los pedidos de bytes o no.You have source code for the server you're communicating with, so you can tell explicitly whether you must convert byte orders or not.

  • Puede trasladar el servidor a MFC.You can port the server to MFC. Esto es bastante fácil de hacer y el resultado es normalmente un código más pequeño y más rápido.This is fairly easy to do, and the result is usually smaller, faster code.

Al trabajar con CAsyncSocket, debe administrar las conversiones de orden de bytes necesarias.Working with CAsyncSocket, you must manage any necessary byte-order conversions yourself. Windows Sockets normaliza el modelo de orden de bytes "Big-endian" y proporciona funciones para realizar la conversión entre este orden y otros.Windows Sockets standardizes the "big-Endian" byte-order model and provides functions to convert between this order and others. Sin embargo, CArchive, que se usa con CSocket, usa el orden opuesto ("Little-endian"), pero CArchive se encarga de los detalles de las conversiones de orden de bytes.CArchive, however, which you use with CSocket, uses the opposite ("little-Endian") order, but CArchive takes care of the details of byte-order conversions for you. Mediante el uso de este orden estándar en las aplicaciones o mediante las funciones de conversión de orden de bytes de Windows Sockets, puede hacer que el código sea más portátil.By using this standard ordering in your applications, or using Windows Sockets byte-order conversion functions, you can make your code more portable.

El caso ideal para utilizar sockets de MFC es cuando se escribe en ambos extremos de la comunicación y se usa MFC en ambos extremos.The ideal case for using MFC sockets is when you are writing both ends of the communication: using MFC at both ends. Si está escribiendo una aplicación que se comunicará con aplicaciones que no son MFC, como un servidor FTP, probablemente necesitará administrar el intercambio de bytes por sí mismo antes de pasar los datos al objeto de almacenamiento, mediante las rutinas de conversión de Windows Sockets NTOHS, ntohl, htons y htonl.If you are writing an application that will communicate with non-MFC applications, such as an FTP server, you will probably need to manage byte-swapping yourself before you pass data to the archive object, using the Windows Sockets conversion routines ntohs, ntohl, htons, and htonl. Más adelante en este artículo se muestra un ejemplo de estas funciones utilizadas para comunicarse con una aplicación que no es MFC.An example of these functions used in communicating with a non-MFC application appears later in this article.

Nota

Cuando el otro extremo de la comunicación no es una aplicación MFC, también debe evitar el streaming de objetos de C++ derivados de CObject en el archivo porque el receptor no podrá controlarlos.When the other end of the communication is not an MFC application, you also must avoid streaming C++ objects derived from CObject into your archive because the receiver will not be able to handle them. Vea la nota en Windows Sockets: usar sockets con archivos.See the note in Windows Sockets: Using Sockets with Archives.

Para obtener más información acerca de los pedidos de bytes, vea la especificación de Windows Sockets, disponible en el Windows SDK.For more information about byte orders, see the Windows Sockets specification, available in the Windows SDK.

Ejemplo de conversión de Byte-OrderA Byte-Order Conversion Example

En el ejemplo siguiente se muestra una función de serialización para un CSocket objeto que utiliza un archivo.The following example shows a serialization function for a CSocket object that uses an archive. También se muestra el uso de las funciones de conversión de orden de bytes en la API de Windows Sockets.It also illustrates using the byte-order conversion functions in the Windows Sockets API.

Este ejemplo presenta un escenario en el que se está escribiendo un cliente que se comunica con una aplicación de servidor que no es MFC para la que no se tiene acceso al código fuente.This example presents a scenario in which you are writing a client that communicates with a non-MFC server application for which you have no access to the source code. En este escenario, debe suponer que el servidor que no es MFC usa el orden de bytes de la red estándar.In this scenario, you must assume that the non-MFC server uses standard network byte order. Por el contrario, la aplicación cliente MFC utiliza un CArchive objeto con un CSocket objeto y CArchive usa el orden de bytes "Little-endian", que es lo contrario del estándar de red.In contrast, your MFC client application uses a CArchive object with a CSocket object, and CArchive uses "little-Endian" byte order, the opposite of the network standard.

Supongamos que el servidor no MFC con el que planea comunicarse tiene un protocolo establecido para un paquete de mensaje como el siguiente:Suppose the non-MFC server with which you plan to communicate has an established protocol for a message packet like the following:

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

En términos de MFC, esto se expresaría como sigue:In MFC terms, this would be expressed as follows:

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

    void Serialize( CArchive& ar );
};

En C++, struct es esencialmente lo mismo que una clase.In C++, a struct is essentially the same thing as a class. La Message estructura puede tener funciones miembro, como la Serialize función miembro declarada anteriormente.The Message structure can have member functions, such as the Serialize member function declared above. La Serialize función miembro podría tener el siguiente aspecto:The Serialize member function might look like this:

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 ejemplo llama a las conversiones de orden de bytes de los datos porque hay una falta de coincidencia en el orden de bytes de la aplicación de servidor que no es MFC en un extremo y que se CArchive usa en la aplicación cliente MFC en el otro extremo.This example calls for byte-order conversions of data because there is a clear mismatch between the byte ordering of the non-MFC server application on one end and the CArchive used in your MFC client application on the other end. En el ejemplo se muestran algunas de las funciones de conversión de orden de bytes que proporciona Windows Sockets.The example illustrates several of the byte-order conversion functions that Windows Sockets supplies. En la tabla siguiente se describen estas funciones.The following table describes these functions.

Funciones de conversión de Windows Sockets Byte-OrderWindows Sockets Byte-Order Conversion Functions

FunciónFunction FinalidadPurpose
ntohsntohs Convertir una cantidad de 16 bits del orden de bytes de la red al orden de bytes del host (Big-Endian a Little-endian).Convert a 16-bit quantity from network byte order to host byte order (big-Endian to little-Endian).
ntohlntohl Convierte una cantidad de 32 bits del orden de bytes de la red al orden de bytes del host (Big-Endian a Little-endian).Convert a 32-bit quantity from network byte order to host byte order (big-Endian to little-Endian).
HtonsHtons Convierte una cantidad de 16 bits del orden de bytes del host al orden de bytes de la red (Little-Endian a big-endian).Convert a 16-bit quantity from host byte order to network byte order (little-Endian to big-Endian).
HtonlHtonl Convierte una cantidad de 32 bits del orden de bytes del host al orden de bytes de la red (Little-Endian a big-endian).Convert a 32-bit quantity from host byte order to network byte order (little-Endian to big-Endian).

Otro punto de este ejemplo es que cuando la aplicación de socket en el otro extremo de la comunicación es una aplicación que no es de MFC, debe evitar realizar una acción similar a la siguiente:Another point of this example is that when the socket application on the other end of the communication is a non-MFC application, you must avoid doing something like the following:

ar << pMsg;

donde pMsg es un puntero a un objeto de C++ derivado de la clase CObject .where pMsg is a pointer to a C++ object derived from class CObject. De esta forma, se enviará información adicional de MFC asociada a los objetos y el servidor no lo entenderá, como si fuera una aplicación MFC.This will send extra MFC information associated with objects and the server will not understand it, as it would if it were an MFC application.

Para más información, consulte:For more information, see:

Consulta tambiénSee also

Windows Sockets en MFCWindows Sockets in MFC