Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
In dit artikel en twee aanvullende artikelen worden verschillende problemen in het programmeren van Windows Sockets uitgelegd. In dit artikel wordt de bytevolgorde behandeld. De andere problemen worden behandeld in de artikelen: Windows Sockets: Blokkeren en Windows Sockets: Tekenreeksen converteren.
Als u klasse CAsyncSocket gebruikt of afleiden, moet u deze problemen zelf beheren. Als u klasse CSocket gebruikt of afgeleid, beheert MFC deze voor u.
Bytevolgorde
Verschillende machinearchitecturen slaan soms gegevens op met behulp van verschillende byteorders. Intel-computers slaan bijvoorbeeld gegevens op in de omgekeerde volgorde van Macintosh-machines (Motorola). De Intel-bytevolgorde, 'little-Endian', is ook de omgekeerde volgorde van de netwerkstandaard 'big-Endian'. In de volgende tabel worden deze termen uitgelegd.
Volgorde van grote en Little-Endian byte
| Bytevolgorde | Betekenis |
|---|---|
| Big-Endian | De belangrijkste byte bevindt zich aan de linkerkant van een woord. |
| Little-Endian | De belangrijkste byte bevindt zich aan de rechterkant van een woord. |
Normaal gesproken hoeft u zich geen zorgen te maken over bytevolgordeconversie voor gegevens die u via het netwerk verzendt en ontvangt, maar er zijn situaties waarin u byteorders moet converteren.
Wanneer u byteorders moet converteren
In de volgende situaties moet u de byteorders converteren.
U geeft informatie door die moet worden geïnterpreteerd door het netwerk, in plaats van de gegevens die u naar een andere computer verzendt. U kunt bijvoorbeeld poorten en adressen doorgeven die het netwerk moet begrijpen.
De servertoepassing waarmee u communiceert, is geen MFC-toepassing (en u hebt hiervoor geen broncode). Dit vraagt om bytevolgordeconversies als de twee machines niet dezelfde bytevolgorde delen.
Wanneer u byteorders niet hoeft te converteren
U kunt in de volgende situaties voorkomen dat byteorders worden geconverteerd:
De machines aan beide uiteinden kunnen niet akkoord gaan met het wisselen van bytes en beide computers gebruiken dezelfde bytevolgorde.
De server waarmee u communiceert, is een MFC-toepassing.
U hebt broncode voor de server waarmee u communiceert, zodat u expliciet kunt zien of u byteorders moet converteren of niet.
U kunt de server overzetten naar MFC. Dit is vrij eenvoudig te doen en het resultaat is meestal kleinere, snellere code.
Als u met CAsyncSocket werkt, moet u zelf eventuele benodigde bytevolgordeconversies beheren. Windows Sockets standaardiseert het bytevolgordemodel 'big-Endian' en biedt functies om te converteren tussen deze volgorde en andere.
CArchive, die u echter gebruikt met CSocket, maakt gebruik van de tegenovergestelde ('little-Endian')-volgorde, maar CArchive zorgt voor de details van byte-orderconversies voor u. Door deze standaardvolgorde in uw toepassingen te gebruiken of windows Sockets byte-order conversiefuncties te gebruiken, kunt u uw code draagbaarder maken.
Het ideale geval voor het gebruik van MFC-sockets is als u beide uiteinden van de communicatie schrijft: waarbij u MFC aan beide uiteinden gebruikt. Als u een toepassing schrijft die communiceert met niet-MFC-toepassingen, zoals een FTP-server, moet u byte-swaping waarschijnlijk zelf beheren voordat u gegevens doorgeeft aan het archiefobject, met behulp van de Windows Sockets-conversieroutines ntohs, ntohl, htons en htonl. Een voorbeeld van deze functies die worden gebruikt bij het communiceren met een niet-MFC-toepassing, wordt verderop in dit artikel weergegeven.
Opmerking
Wanneer het andere einde van de communicatie geen MFC-toepassing is, moet u ook voorkomen dat C++-objecten die zijn afgeleid van CObject in uw archief worden gestreamd, omdat de ontvanger deze niet kan verwerken. Zie de opmerking in Windows Sockets: Sockets gebruiken met archieven.
Zie de Specificatie van Windows Sockets, die beschikbaar is in de Windows SDK voor meer informatie over byteorders.
Voorbeeld van een Byte-Order conversie
In het volgende voorbeeld ziet u een serialisatiefunctie voor een CSocket object dat gebruikmaakt van een archief. Het illustreert ook het gebruik van de bytevolgordeconversiefuncties in de Windows Sockets-API.
In dit voorbeeld ziet u een scenario waarin u een client schrijft die communiceert met een niet-MFC-servertoepassing waarvoor u geen toegang hebt tot de broncode. In dit scenario moet u ervan uitgaan dat de niet-MFC-server standaard bytevolgorde van het netwerk gebruikt. Uw MFC-clienttoepassing gebruikt daarentegen een CArchive object met een CSocket object en CArchive maakt gebruik van bytevolgorde 'little-Endian', het tegenovergestelde van de netwerkstandaard.
Stel dat de niet-MFC-server waarmee u wilt communiceren, een tot stand gebracht protocol heeft voor een berichtpakket, zoals hieronder:
struct Message
{
long MagicNumber;
unsigned short Command;
short Param1;
long Param2;
};
In MFC-termen zou dit als volgt worden uitgedrukt:
struct Message
{
long m_lMagicNumber;
short m_nCommand;
short m_nParam1;
long m_lParam2;
void Serialize(CArchive &ar);
};
In C++is een struct in feite hetzelfde als een klasse. De Message structuur kan lidfuncties hebben, zoals de Serialize bovenstaande lidfunctie. De Serialize lidfunctie kan er als volgt uitzien:
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 dit voorbeeld zijn bytevolgordewisselingen van gegevens noodzakelijk omdat er een duidelijke mismatch is tussen de bytevolgorde van de niet-MFC-servertoepassing aan de ene kant en het CArchive dat in uw MFC-clienttoepassing wordt gebruikt aan de andere kant. In het voorbeeld ziet u een aantal van de bytevolgordeconversiefuncties die Door Windows Sockets worden geleverd. In de volgende tabel worden deze functies beschreven.
Windows Sockets Byte-Order Conversiefuncties
| Functie | Doel |
|---|---|
| ntohs | Converteer een 16-bits hoeveelheid van netwerk bytevolgorde naar host bytevolgorde (big-Endian naar little-Endian). |
| ntohl | Converteer een 32-bits hoeveelheid van netwerk bytevolgorde naar host bytevolgorde (big-Endian naar little-Endian). |
| Htons | Converteer een 16-bits hoeveelheid van host-bytevolgorde naar netwerk bytevolgorde (little-Endian naar big-Endian). |
| Htonl | Converteer een 32-bits hoeveelheid van host bytevolgorde naar netwerk bytevolgorde (little-Endian naar big-Endian). |
Een ander punt van dit voorbeeld is dat wanneer de sockettoepassing aan het andere uiteinde van de communicatie een niet-MFC-toepassing is, u moet voorkomen dat u iets doet zoals het volgende:
ar << pMsg;
waar pMsg is een aanwijzer naar een C++-object dat is afgeleid van klasse CObject. Hiermee wordt extra MFC-informatie verzonden die is gekoppeld aan objecten en de server begrijpt deze niet, net als bij een MFC-toepassing.
Voor meer informatie, zie: