This article and two other related articles explain some issues in Windows Sockets programming. This article introduces byte sorting. Other problems are described in the article Windows Sockets: blocking and Windows Sockets: Converting strings.
If you use the CAsyncSocket class or derive from it, you need to manage these issues on your own. If you use the CSocket class or derive from it,
Manage them.
Byte sorting
Different computer structures sometimes use different bytes to store data. For example, Intel-based computers store data in sequence with Macintosh
(Motorola) computers. Intel's byte sequence is called "Little-Endian", which is the opposite of the network standard "Big-Endian. Lower table Solution
Describe these terms.
Big-Endian and Little-Endian byte sorting
Byte sorting |
Description |
Big-Endian |
The most important byte is on the left side of the word. |
Little-Endian |
The most important byte is on the right side of the word. |
Generally, you do not have to worry about the byte sequence conversion of the data sent and received over the network, but in some cases, you must convert the byte sequence.
When must the byte order be converted?
In the following cases, you must convert the byte sequence:
- The transmitted information needs to be interpreted by the Network (opposite to the data sent to another computer ). For example, the port and address may be transmitted.
It must be understood as a network.
- The server application that communicates with it is not an MFC Application (and does not have its source code ). If the two computers do not share the same byte
Sort, the bytes must be converted in sequence.
When to convert byte order
In the following cases, you do not need to convert the byte sequence:
- Computers at both ends can agree not to swap bytes, and the two computers use the same byte order.
- The server that communicates with it is the MFC application.
- The source code of the server that communicates with it, so you can clearly determine whether bytes must be converted.
- You can port the server to MFC. This is quite easy, and the code is usually smaller and faster.
When using CAsyncSocket, you must manage any required bytes for sequential conversion. Windows Sockets
Order Model standardization, and provides functions for conversion between the order and other orders. However, the CArchive used with CSocket
Reverse Order ("Little-Endian"),CArchiveManages the details of byte sequence conversion for you. By using this standard in applications
Sort, or use the Windows Sockets byte sequence conversion function to enhance code portability.
The most suitable case for using an MFC socket is when both ends of communication are written: MFC is used at both ends. If you are writing a non-MFC application
Communication applications (such as FTP servers), before passing data to the archive object, you may need to use the Windows Sockets conversion routine
Ntohs,Ntohl,HtonsAndHtonlManage byte exchanges by yourself. This article will show the functions for communicating with non-MFC Applications later.
Example.
Note:When the other end of the communication is not an MFC applicationCObjectThe derived C ++ object is input as a stream
Because the acceptor cannot process them. See Windows Sockets: Instructions for using an archived socket.
For more information about the byte sequence, see the Windows Sockets specification in Platform SDK.
Byte sequence conversion example
The following example showsCSocketA serialization function of an object. It also explains how to use
Byte sequence conversion function.
This example shows that you are writing a client program that communicates with a non-MFC server application, and you have not accessed the server application.
Source code permission. In this case, the non-MFC server must use the standard network byte sequence. On the contrary, the MFC client application
CSocketObject usageCArchiveObject, andCArchiveUses the "Little-Endian" byte sequence that is opposite to the network standard.
Assume that the non-MFC server to communicate with has the following established message packet protocol:
struct Message { long MagicNumber; unsigned short Command; short Param1; long Param2; };
The above content is represented in MFC terminology:
struct Message { long m_lMagicNumber; short m_nCommand; short m_nParam1; long m_lParam2; void Serialize
( CArchive& ar ); };
In C ++,StructIt is essentially the same as a class.Message
The structure can have member functions, as stated aboveSerialize
Member functions.
Serialize
The member functions may be in the following format:
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);
}
}
This example requires Data byte sequence conversion, because the byte sorting of one end of the non-MFC server application and the other end used in the MFC client applicationCArchiveObviously does not match. This example illustrates several byte sequence conversion functions provided by Windows Sockets. The following table describes these functions.
Windows Sockets byte sequence Conversion Function
Function |
Function |
Ntohs |
Converts the number of 16 bits from the network byte sequence to the host byte sequence (from Big-Endian to Little-Endian ). |
Ntohl |
The 32-bit number is converted from the network byte sequence to the host byte sequence (from Big-Endian to Little-Endian ). |
Htons |
Converts the number of 16 bits from the host bytes to the network byte order (from Little-Endian to Big-Endian ). |
Htonl |
The 32-bit number is converted from the host byte sequence to the network byte sequence (from Little-Endian to Big-Endian ). |
Another important point in this example is that when the socket application at the other end of the communication is a non-MFC application, you must avoid operations such as the following statements:
ar pMsg;
HerepMsg
YesCObjectClass-derived pointer to a C ++ object. This will send redundant MFC information associated with the object, and the server does not understand this information, because it is understood only when the server is an MFC application.