Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Cet article et deux éléments auxiliaires expliquent plusieurs problèmes relatifs à la programmation Windows Sockets.Cet article décrit l'ordre d'octet.Les autres problèmes sont décrites dans les articles : Windows Sockets : Bloquer et Windows Sockets : convertir des chaînes.
Si vous utilisez ou dérivez de la classe CAsyncSocket, vous devrez gérer ces problèmes vous-même.Si vous utilisez ou dérivez de la classe CSocket, MFC les gère pour vous.
L'ordre d'octet
Les différentes architectures d'ordinateur stockent parfois des données à l'aide de différentes marque d'ordre d'octet.Par exemple, les ordinateurs Intel-basés stockent des données dans l'ordre inverse d'ordinateurs Macintosh (Motorola).La marque d'ordre d'octet Intel, appelée « avec primauté des octets de poids faible, » est également l'inverse commande de « avec primauté des octets de poids fort » standard de réseau.Le tableau suivant décrit ces termes.
Grandes et avec primauté des octets de poids faible l'ordre d'octet
L'ordre d'octet |
Signification |
|---|---|
Avec primauté des octets de poids fort |
L'octet de poids fort est sur l'extrémité gauche d'un mot. |
Avec primauté des octets de poids faible |
l'octet de poids fort est sur l'extrémité droite d'un mot. |
En général, vous n'avez pas à vous préoccuper de la conversion de marque d'ordre d'octet pour les données que vous envoyez et acceptez sur le réseau, mais il existe des situations dans lesquelles vous devez convertir les marqueurs d'ordre d'octet.
Lorsque vous devez convertir les marqueurs d'ordre d'octet
Vous devez convertir les marqueurs d'ordre d'octet dans les situations suivantes :
Vous passez des informations qui doivent être interprétées par le réseau, par opposition à les données que vous envoyez à un autre ordinateur.Par exemple, vous pouvez passer les ports et les adresses, que le réseau doit inclure.
L'application serveur avec laquelle vous communiquez n'est pas une application MFC (et que vous n'avez pas le code source pour arrêter).Ce appels pour les conversions de marque d'ordre d'octet si les deux ordinateurs partagent pas même ordre d'octet.
Lorsque vous ne devez pas convertir des marques d'ordre d'octet
Vous pouvez éviter le travail de convertir des marques d'ordre d'octet dans les situations suivantes :
Les ordinateurs sur les deux extrémités peuvent accepter de ne pas échanger des octets, et les deux ordinateurs utilisent la même marque d'ordre d'octet.
Le serveur que vous communiquez avec est une application MFC.
Vous avez le code source du serveur que vous communiquez avec, vous pouvez demander explicitement si vous devez convertir les marqueurs d'ordre d'octet ou pas.
Vous pouvez déplacer le serveur aux MFC.Il est relativement simple ce faire, et le résultat est généralement plus petit, plus rapide code.
Vous utilisez CAsyncSocket, vous devez gérer toutes les conversions nécessaires de marque d'ordre d'octet vous-même.Windows Sockets permet de normaliser le modèle « avec primauté des octets de poids fort » de marque d'ordre d'octet et fournit des fonctions pour effectuer des conversions entre cette commande et autres.CArchive, cependant, que vous utilisez avec CSocket, utilise (« avec primauté des octets de poids faible ») l'ordre opposé, mais CArchive gérer tous les détails des conversions de marque d'ordre d'octet pour vous.À l'aide de cette norme classement dans vos applications, ou à l'aide de fonctions de conversion de marque d'ordre d'octet Windows Sockets, vous pouvez rendre votre code plus portable.
Le point droit de l'idéal pour l'utilisation des sockets MFC est lorsque vous écrivez les deux extrémités de la communication : utilisation de MFC aux deux extrémités.Si vous écrivez une application qui communiquera avec les applications non-MFC, comme un serveur FTP, vous devrez probablement gérer l'octet-échange vous-même avant de passer des données à l'objet archive, à l'aide de les routines de conversion Windows Sockets ntohs, ntohl, htons, et htonl.Un exemple de ces fonctions utilisé dans la communication avec une application non-MFC apparaît ultérieurement dans cet article.
[!REMARQUE]
Lorsque l'autre extrémité de la communication n'est pas une application MFC, vous devez également éviter d'un flux d'objets C++ dérivés d' CObject dans votre fichier parce que le récepteur ne pourra pas les gérer.Voir la remarque dans Windows Sockets : Utilisation des sockets avec des archives.
Pour plus d'informations sur les marqueurs d'ordre d'octet, consultez la spécification Windows Sockets, disponible dans Kit de développement logiciel Windows.
Un exemple de conversion de marque d'ordre d'octet
L'exemple suivant illustre une fonction de sérialisation pour un objet d' CSocket qui utilise une archive.Il illustre également à l'aide de les fonctions de conversion de marque d'ordre d'octet dans l'API Windows Sockets.
Cet exemple présente un scénario dans lequel vous écrivez un client qui communique avec une application serveur non-MFC pour laquelle vous n'avez pas accès au code source.Dans ce scénario, vous devez supposer que le serveur non-MFC utilise l'ordre d'octet du réseau standard.En revanche, votre application cliente MFC utilise un objet d' CArchive à un objet d' CSocket , et la marque d'ordre d'octet « avec primauté des octets de poids faible » d'utilisations d' CArchive , le contraire de la norme de réseau.
Supposez que le serveur non-MFC avec lequel vous projetez de communiquer a un protocole être généré pour un à en-tête pack de message comme suit :
struct Message
{
long MagicNumber;
unsigned short Command;
short Param1;
long Param2;
};
Dans la terminologie de MFC, cette séquence est exprimé comme suit :
struct Message
{
long m_lMagicNumber;
short m_nCommand;
short m_nParam1;
long m_lParam2;
void Serialize( CArchive& ar );
};
En C++, struct est essentiellement la même chose qu'une classe.La structure d' Message peut avoir des fonctions membres, telles que la fonction membre d' Serialize déclarée ci-dessus.La fonction membre d' Serialize peut se présenter comme suit :
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);
}
}
Les cet exemple appelle pour les conversions de marque d'ordre d'octet les données qu'il existe une incompatibilité claire entre l'ordre d'octet de l'application serveur non-MFC sur une extrémité et CArchive utilisé dans votre application cliente MFC sur l'autre se terminent.L'exemple illustre plusieurs de la conversion de marque d'ordre d'octet fonctionne que des fournit Windows Sockets.Le tableau suivant décrit ces fonctions.
Fonctions de conversion de marque d'ordre d'octet Windows Sockets
Fonction |
Objectif |
|---|---|
ntohs |
Convertit une valeur 16 bits de l'ordre d'octet du réseau pour héberger la marque d'ordre d'octet (avec primauté des octets de poids fort à avec primauté des octets de poids faible). |
ntohl |
Convertit une valeur 32 bits de l'ordre d'octet du réseau pour héberger la marque d'ordre d'octet (avec primauté des octets de poids fort à avec primauté des octets de poids faible). |
Htons |
Convertit une valeur 16 bits de marque d'ordre d'octet hôte à l'ordre d'octet le réseau (avec primauté des octets de poids faible à avec primauté des octets de poids fort). |
Htonl |
Convertit une valeur 32 bits de marque d'ordre d'octet hôte à l'ordre d'octet le réseau (avec primauté des octets de poids faible à avec primauté des octets de poids fort). |
Un autre point de cet exemple est que lorsque l'application de socket sur l'autre extrémité de la communication est une application non-MFC, vous devez éviter de provoquer des éléments semblables aux suivants :
ar << pMsg;
où pMsg est un pointeur vers un objet C++ dérivé de la classe CObject.Il envoie les informations de MFC de frais supplémentaires associées à des objets et le serveur ne les inclut pas, comme elles s'il s'agissait d'une application MFC.
Pour plus d'informations, consultez :