Windows Sockets: określanie kolejności bajtów
W tym artykule oraz dwa artykuły Pomocnik wyjaśnić kilka problemów podczas programowania Windows Sockets.Ten artykuł obejmuje zapisu bajtów.Inne zagadnienia zostały omówione w artykułach: Windows Sockets: blokowanie i Windows Sockets: Konwertowanie ciągów.
Jeśli używasz lub pochodzić od klasy CAsyncSocket, musisz samodzielnie zarządzać tych problemów.Jeśli używasz lub pochodzić od klasy CSocketFile, CSocket, MFC zarządza je dla Ciebie.
Kolejność bajtów
Architektura komputerów różnych przechowują dane przy użyciu różnych bajt zamówień.Na przykład komputerów opartych na architekturze Intel przechowywać dane w odwrotnej kolejności niż komputery Macintosh (Motorola).Kolejność bajtów Intel, o nazwie "little-Endian," jest również odwrotnej kolejności "big-Endian" standard sieci.W poniższej tabeli opisano te warunki.
Kolejność bajtów big - i Little-Endian
Kolejność bajtów |
Znaczenie |
---|---|
Big-Endian |
Najbardziej znaczący bajt znajduje się na lewym końcu wyrazu. |
Little-Endian |
Najbardziej znaczący bajt znajduje się na prawym końcu wyrazu. |
Zazwyczaj nie trzeba martwić się o konwersji kolejność bajtów danych, które można wysyłać i odbierać przez sieć, ale istnieją sytuacje, w których należy przekonwertować bajt zamówień.
Kiedy należy przekonwertować bajt zamówień
Należy przekonwertować bajt zamówień w następujących sytuacjach:
Są przekazywanie informacji, które należy interpretować w sieci, w przeciwieństwie do danych, które wysyłasz do innego komputera.Na przykład, może przekazać portów i adresów, które należy zrozumieć sieci.
Aplikacja serwera, z którym jest nawiązywana nie jest aplikacja MFC (i nie masz dla niego kod źródłowy).Wymaga konwersji kolejność bajtów Jeśli obu komputerów nie korzystają z tej samej kolejności bajtów.
Kiedy nie musisz przekonwertować bajt zamówień
Można uniknąć pracy Konwertowanie zamówień bajt w następujących sytuacjach:
Maszyny na obu końcach może zgodzić się nie do wymiany bajtów, a obie maszyny Użyj tej samej kolejności bajtów.
Serwer, z którym nawiązywana jest to aplikacja MFC.
Masz kod źródłowy dla serwera, z którym nawiązywana, dzięki czemu można sprawdzić jawnie czy należy przekonwertować bajt zamówień czy nie.
Można portu serwera do biblioteki MFC.Jest to dość proste do zrobienia, a wynik jest zazwyczaj mniejsze, szybsze kodu.
Praca z CAsyncSocket, zostanie jakakolwiek konwersja niezbędne kolejność bajtów trzeba zarządzać.Windows Sockets standaryzuje modelu kolejność bajtów "big-Endian" i zawiera funkcje do konwersji między to zamówienie i innych.CArchive, jednakże używanego z CSocketFile, CSocket, używa odwrotnej kolejności ("little-Endian"), ale CArchive dba o szczegóły konwersji kolejność bajtów dla Ciebie.Za pomocą tej standardowej kolejności w aplikacji, lub za pomocą funkcji konwersji kolejność bajtów Windows Sockets, użytkownik może poprawić czytelność kodu bardziej przenośne.
Jest idealnym rozwiązaniem w przypadku przy użyciu gniazd MFC pisząc oba końce komunikatu: przy użyciu biblioteki MFC na obu końcach.Podczas pisania aplikacji, która będzie komunikować się z aplikacji innych niż MFC, takich jak serwer FTP będzie prawdopodobnie trzeba zarządzać bajt wymiany samodzielnie przed przekazywania danych do obiektu archiwum przy użyciu usługi Windows Sockets procedury konwersji ntohs, ntohl, htons, i htonl.Przykładem tych funkcji używanych w komunikowaniu się z aplikacji MFC nie pojawia się w dalszej części tego artykułu.
[!UWAGA]
Gdy drugi koniec komunikatu nie jest aplikacja MFC, również należy unikać przesyłania strumieniowego z obiektami C++ pochodzące z CObject do archiwum, ponieważ odbiorca nie będzie mógł je obsłużyć.Patrz Uwaga do Windows Sockets: przy użyciu gniazd z archiwum.
Aby uzyskać więcej informacji na temat zamówień bajt zobacz specyfikację Windows Sockets, dostępna w Windows SDK.
Przykład konwersji kolejność bajtów
W poniższym przykładzie pokazano funkcję serializacji dla CSocket obiekt używający archiwum.Przedstawiono także, przy użyciu funkcji konwersji kolejność bajtów w interfejsu API Windows Sockets.
W tym przykładzie przedstawiono scenariusz, w którym zapisuje się klient, który komunikuje się z aplikacją serwera-biblioteki MFC, dla którego nie masz dostępu do kodu źródłowego.W tym scenariuszu należy przyjąć, że serwer MFC nie używa standardowego sieciowa kolejność bajtów.Natomiast używa aplikacja kliencka MFC CArchive obiekt z CSocket obiektu, i CArchive wykorzystuje kolejność bajtów "little-Endian", stanowi przeciwieństwo standard sieci.
Załóżmy, że serwer biblioteki MFC, z którą zamierzasz komunikowania się zawiera protokół umożliwiający pakietu komunikatu w następujący:
struct Message
{
long MagicNumber;
unsigned short Command;
short Param1;
long Param2;
};
W kategoriach MFC to wyraża się następująco:
struct Message
{
long m_lMagicNumber;
short m_nCommand;
short m_nParam1;
long m_lParam2;
void Serialize( CArchive& ar );
};
W języku C++ struct jest zasadniczo tak samo jak klasy.Message Struktura może mieć funkcji elementów członkowskich, takich jak Serialize Członkowskich funkcja zadeklarowana powyżej.Serialize Funkcji składowej może wyglądać następująco:
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);
}
}
W tym przykładzie wzywa do konwersji kolejność bajtów danych, ponieważ jest jasne, niezgodność między bajt zamawiania-biblioteki MFC aplikacji serwera na jednym końcu i CArchive wykorzystywane w aplikacji MFC klienta na drugim końcu.Przykład ilustruje szereg funkcji konwersji kolejność bajtów, które dostarcza usługi Windows Sockets.W poniższej tabeli opisano te funkcje.
Funkcje konwersji kolejność bajtów usługi Windows Sockets
Funkcja |
Cel |
---|---|
ntohs |
Przeliczenie ilości 16-bitowych z sieciowa kolejność bajtów do hosta kolejność bajtów (big-Endian na little-Endian). |
ntohl |
Przeliczenie ilości 32-bitowe z sieciowa kolejność bajtów do hosta kolejność bajtów (big-Endian na little-Endian). |
Htons |
Przeliczenie ilości 16-bitowych z hosta kolejność bajtów do sieciowa kolejność bajtów (little-Endian do big-Endian). |
Htonl |
Przeliczenie ilości 32-bitowe z hosta kolejność bajtów do sieciowa kolejność bajtów (little-Endian do big-Endian). |
Inny punkt w tym przykładzie jest że gdy aplikacja gniazda na drugim końcu komunikatu jest aplikacją biblioteki MFC, należy unikać coś w następujący sposób:
ar << pMsg;
gdzie pMsg jest wskaźnik do obiektu C++ pochodną klasy CObject.To będzie wysyłać dodatkowe informacje MFC skojarzone z obiektami i serwer nie będzie zrozumieć, jak gdyby był on aplikacji MFC.
Aby uzyskać więcej informacji, zobacz: