Windows Sockets: Pořadí bajtů
Tento článek a dva příbuzné články popisují několik problémů v programování rozhraní Windows Sockets.Tento článek popisuje pořadí bajtů.Další problémy jsou uvedeny v článcích: Windows Sockets: blokování a Windows Sockets: převod řetězce.
Pokud používáte nebo jsou odvozeny ze třídy CAsyncSocket, je nutné spravovat tyto problémy sami.Pokud používáte nebo jsou odvozeny ze třídy CSocket, spravuje knihovny MFC, je pro vás.
Pořadí bytů
Různou architekturou někdy ukládají data pomocí různých bajt objednávky.Počítače platformy Intel například ukládat data v obráceném pořadí počítačů Macintosh (Motorola).Pořadí bajtů Intel, nazývané "little-Endian, je naopak sítě standardní pořadí"big Endian".Následující tabulka popisuje tyto podmínky.
Pořadí bytů big a Little-Endian
Pořadí bytů |
Význam |
---|---|
Big-Endian |
Nejvýznamnější bajt je na levém konci slova. |
Little-Endian |
Nejvýznamnější bajt je na pravém konci slova. |
Obvykle není nutné starat o převodu pořadí bytů pro data, která můžete odesílat a přijímat prostřednictvím sítě, ale existují situace, ve kterých je nutné převést bajtové objednávky.
Pokud je nutné převést bajtové objednávky
Je třeba převést bajtové objednávky v následujících situacích:
Předáváte informace, které musí být vykládány v síti, na rozdíl od dat, která odesíláte do jiného počítače.Například můžete předat porty a adresy, které je třeba pochopit v síti.
Serverové aplikace, se kterou komunikujete není aplikace knihovny MFC (a nemáte pro něj zdrojový kód).To vyžaduje převod pořadí bajtů Pokud dvou počítačů Nesdílet stejné pořadí bajtů.
Pokud není nutné převést bajtové objednávky
Můžete se vyhnout práci převod bajt objednávky v následujících situacích:
Stroje na obou stranách lze dohodnou, že výměna bajtů a oba počítače používají stejné pořadí bajtů.
Server, který komunikuje se je aplikace knihovny MFC.
Máte zdrojový kód pro server, ke kterému komunikujete, takže můžete explicitně zjistit, zda je nutné převést bajtové objednávky, nebo ne.
Můžete port serveru ke knihovně MFC.To je poměrně snadné a výsledek je obvykle menší a rychlejší kód.
Práce s CAsyncSocket, musí všechny nezbytné pro pořadí bajtů převody spravovat sami.Rozhraní Windows Sockets standardizuje pořadí bytů big-Endian"model a poskytuje funkce pro převod mezi tuto objednávku a další.CArchive, ale které můžete s CSocket, používá v opačném pořadí ("little-Endian"), ale CArchive pečuje o podrobnosti o převody pořadí bytů pro vás.Pomocí této standardní řazení ve vašich aplikacích, nebo pomocí funkce rozhraní Windows Sockets pořadí bajtů, můžete vytvořit kód obecnější.
Ideálním případem použití soketů knihovny MFC je, když vytváříte obě strany komunikace, používáte knihovnu MFC na obou koncích.Pokud píšete aplikaci, která bude komunikovat s non-MFC aplikace, například serveru FTP bude pravděpodobně třeba spravovat byte výměna sami před předání dat do archivu objektu pomocí převodní rutiny rozhraní Windows Sockets ntohs, ntohl, htons, a htonl.Příkladem těchto funkcí v komunikaci s non-MFC aplikace, zobrazí se později v tomto článku.
[!POZNÁMKA]
Konci komunikace není aplikace knihovny MFC, je také třeba se vyvarovat streaming objektů jazyka C++ z CObject do archivu protože příjemce nebylo možné zpracovat je.Viz poznámka v Windows Sockets: pomocí soketů s archivy.
Další informace o bajt objednávky naleznete ve specifikaci rozhraní Windows Sockets, k dispozici v Windows SDK.
Příklad převodu pořadí bajtů
Následující příklad ukazuje funkci serializace CSocket objekt, který používá archiv.Ukazuje také pomocí funkcí pro převod pořadí bajtů v rozhraní API Windows Sockets.
V tomto příkladu představuje scénář, ve kterém vytváříte klient komunikuje s non-MFC serverové aplikace, ke kterým máte přístup ke zdrojovému kódu.V tomto případě Předpokládejme, že server non-MFC používá standardní síťovém pořadí bajtů.Naopak klientská aplikace knihovny MFC používá CArchive objekt s CSocket objekt, a CArchive používá pořadí bajtů "little-Endian, naopak standardní sítě.
Předpokládejme, že server non-MFC, se kterým chcete komunikovat má zavedený protokol pro paket zprávy podobné následujícímu:
struct Message
{
long MagicNumber;
unsigned short Command;
short Param1;
long Param2;
};
Z hlediska knihovny MFC to by být vyjádřen takto:
struct Message
{
long m_lMagicNumber;
short m_nCommand;
short m_nParam1;
long m_lParam2;
void Serialize( CArchive& ar );
};
V jazyce C++ struct je v podstatě totéž jako třída.Message Struktura může mít členské funkce, jako Serialize členské funkce deklarována výše.Serialize Členské funkce může vypadat například takto:
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);
}
}
V tomto příkladu volá pro pořadí bajtů převody dat, protože je jasný nesoulad mezi bajt objednání non-MFC aplikace serveru na jednom konci a CArchive používán na opačném konci klientské aplikace knihovny MFC.Příklad ukazuje několik funkcí pro převod pořadí bajtů, které dodává rozhraní Windows Sockets.Tyto funkce jsou popsány v následující tabulce.
Windows Sockets Byte-Order funkce převodu
Funkce |
Účel |
---|---|
ntohs |
Převeďte 16bitové množství z pořadí síťových bajtů pro pořadí bajtů hostitele (big-Endian na little-Endian). |
ntohl |
Převeďte množství 32-bit z pořadí síťových bajtů pro pořadí bajtů hostitele (big-Endian na little-Endian). |
Htons |
Převeďte 16bitové množství z pořadí bajtů hostitele pořadí síťových bajtů (little-Endian na big-Endian). |
Htonl |
Převeďte množství 32-bit pořadí bajtů hostitele na síťovém pořadí bajtů (little-Endian na big-Endian). |
Jiný bod tohoto příkladu je, že při použití soketu na druhém konci komunikace je non-MFC aplikace, je třeba se vyvarovat něco jako následující:
ar << pMsg;
kde pMsg je ukazatel na objekt jazyka C++, který je odvozen od třídy CObject.Toto odešle dodatečné informace knihovny MFC přidružené objekty a server nebude rozumět, jako kdyby byla aplikace knihovny MFC.
Další informace naleznete v části: