Aracılığıyla paylaş


Windows Yuvaları: Bayt Sıralama

Bu makale ve iki yardımcı makale, Windows Yuvaları programlamadaki çeşitli sorunları açıklar. Bu makale bayt sıralamasını kapsar. Diğer sorunlar şu makalelerde ele alınmıştır: Windows Yuvaları: Engelleme ve Windows Yuvaları: Dizeleri Dönüştürme.

CAsyncSocket sınıfını kullanıyor veya sınıfından türetilirseniz, bu sorunları kendiniz yönetmeniz gerekir. CSocket sınıfını kullanır veya bu sınıftan türetilirseniz, MFC bunları sizin için yönetir.

Bayt Sıralama

Farklı makine mimarileri bazen verileri farklı bayt siparişlerini kullanarak depolar. Örneğin, Intel tabanlı makineler verileri Macintosh (Motorola) makinelerinin ters sırasına göre depolar. "little-Endian" olarak adlandırılan Intel bayt sırası aynı zamanda ağ standardı "big-Endian" sırasının tersidir. Aşağıdaki tabloda bu terimler açıklanmaktadır.

Big-and Little-Endian Byte Ordering

Bayt sıralama Anlamı
Big-Endian En önemli bayt bir sözcüğün sol ucundadır.
Küçük Endian dili En önemli bayt bir sözcüğün sağ ucundadır.

Genellikle, ağ üzerinden gönderdiğiniz ve aldığınız veriler için bayt sırası dönüştürme konusunda endişelenmeniz gerekmez, ancak bayt siparişlerini dönüştürmeniz gereken durumlar vardır.

Bayt Siparişlerini Dönüştürmeniz Gerektiğinde

Aşağıdaki durumlarda bayt siparişlerini dönüştürmeniz gerekir:

  • Başka bir makineye gönderdiğiniz verilerin aksine ağ tarafından yorumlanması gereken bilgileri geçiriyorsunuz. Örneğin, ağın anlaması gereken bağlantı noktalarını ve adresleri geçirebilirsiniz.

  • İletişimde olduğunuz sunucu uygulaması bir MFC uygulaması değildir (ve bunun için kaynak kodunuz yoktur). Bu, iki makine aynı bayt sıralamasını paylaşmazsa bayt siparişi dönüştürmelerini çağırır.

Bayt Siparişlerini Dönüştürmeniz Gerekmediğinde

Aşağıdaki durumlarda bayt siparişlerini dönüştürme işinden kaçınabilirsiniz:

  • Her iki uçta bulunan makineler baytları değiştirmeme konusunda anlaşabilir ve her iki makine de aynı bayt sırasını kullanır.

  • İletişimde olduğunuz sunucu bir MFC uygulamasıdır.

  • İletişimde olduğunuz sunucu için kaynak kodunuz var, bu nedenle bayt siparişlerini dönüştürmeniz gerekip gerekmediğini açıkça anlayabilirsiniz.

  • Sunucuyu MFC'ye taşıyabilirsiniz. Bunu yapmak oldukça kolaydır ve sonuç genellikle daha küçük ve daha hızlı bir koddur.

CAsyncSocket ile çalışırken, gerekli bayt sırası dönüştürmelerini kendiniz yönetmeniz gerekir. Windows Yuvaları , "big-Endian" bayt sırası modelini standart hale getirir ve bu sıra ile diğerleri arasında dönüştürme işlevleri sağlar. Ancak CSocket ile kullandığınız CArchive, tam tersi ("little-Endian") sırasını kullanır, ancak CArchive bayt sırası dönüştürmelerinin ayrıntılarını sizin için halleder. Uygulamalarınızda bu standart sıralamayı veya Windows Yuvaları bayt sırası dönüştürme işlevlerini kullanarak kodunuzu daha taşınabilir hale getirebilirsiniz.

MFC yuvalarını kullanmak için ideal durum, iletişimin her iki ucunu da yazdığınızdadır: her iki uçta da MFC kullanmak. FTP sunucusu gibi MFC olmayan uygulamalarla iletişim kuracak bir uygulama yazıyorsanız, windows yuvaları dönüştürme yordamları ntohs, ntohl, htons ve htonl kullanarak arşiv nesnesine veri geçirmeden önce bayt değiştirme işlemini yönetmeniz gerekebilir. Bu makalenin devamında MFC olmayan bir uygulamayla iletişim kurarken kullanılan bu işlevlerin bir örneği görüntülenir.

Dekont

İletişimin diğer ucu bir MFC uygulaması olmadığında, alıcı bunları işleyemeyeceğinden CObject , arşivinize türetilen C++ nesnelerinin akışını yapmaktan da kaçınmanız gerekir. Windows Yuvaları: Yuvaları Arşivlerle Kullanma başlığı altındaki nota bakın.

Bayt siparişleri hakkında daha fazla bilgi için Bkz. Windows SDK'sında bulunan Windows Yuvaları belirtimi.

Bayt Sırası Dönüştürme Örneği

Aşağıdaki örnekte, arşiv kullanan bir CSocket nesne için serileştirme işlevi gösterilmektedir. Ayrıca Windows Yuvaları API'sindeki bayt sırası dönüştürme işlevlerinin kullanılmasını da gösterir.

Bu örnek, kaynak koduna erişiminiz olmayan MFC olmayan bir sunucu uygulamasıyla iletişim kuran bir istemci yazdığınız bir senaryoyu sunar. Bu senaryoda, MFC olmayan sunucunun standart ağ bayt sırasını kullandığını varsaymalısınız. Buna karşılık, MFC istemci uygulamanız nesne içeren bir CArchiveCSocket nesne kullanır ve CArchive ağ standardının tam tersi olan "little-Endian" bayt sırasını kullanır.

İletişim kurmayı planladığınız MFC dışı sunucunun, aşağıdaki gibi bir ileti paketi için belirlenmiş bir protokole sahip olduğunu varsayalım:

struct Message
{
   long MagicNumber;
   unsigned short Command;
   short Param1;
   long Param2;
};

MFC açısından bu, aşağıdaki gibi ifade edilir:

struct Message
{
   long m_lMagicNumber;
   short m_nCommand;
   short m_nParam1;
   long m_lParam2;

   void Serialize(CArchive &ar);
};

C++'ta , struct temelde bir sınıfla aynıdır. Yapı, Message yukarıda bildirilen üye işlevi gibi üye işlevlerine Serialize sahip olabilir. Serialize Üye işlevi şöyle görünebilir:

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);
   }
}

Bu örnekte, bir uçta MFC olmayan sunucu uygulamasının bayt sıralaması ile diğer uçtaki CArchive MFC istemci uygulamanızda kullanılan arasında net bir uyuşmazlık olduğundan verilerin bayt sırası dönüştürmeleri çağrılır. Örnekte, Windows Yuvalarının sağladığı bayt sırası dönüştürme işlevlerinin birkaçı gösterilmektedir. Aşağıdaki tabloda bu işlevler açıklanmaktadır.

Windows Yuvaları Bayt Sırası Dönüştürme İşlevleri

Function Purpose
ntohs 16 bitlik bir miktarı ağ bayt siparişinden konak bayt siparişine dönüştürün (big-Endian'dan little-Endian'a).
ntohl 32 bitlik bir miktarı ağ bayt siparişinden konak bayt siparişine dönüştürün (big-Endian'dan little-Endian'a).
Htons 16 bitlik bir miktarı konak bayt siparişinden ağ bayt siparişine (little-Endian-big-Endian) dönüştürün.
Htonl 32 bitlik bir miktarı konak bayt siparişinden ağ bayt siparişine (little-Endian-big-Endian) dönüştürün.

Bu örneğin bir diğer noktası, iletişimin diğer ucundaki yuva uygulaması MFC olmayan bir uygulama olduğunda aşağıdakine benzer bir işlem yapmaktan kaçınmanız gerektiğidir:

ar << pMsg;

burada pMsg sınıfından CObjecttüretilen bir C++ nesnesinin işaretçisidir. Bu işlem nesnelerle ilişkilendirilmiş ek MFC bilgileri gönderir ve sunucu bunu anlamayacaktır, MFC uygulamasıysa olduğu gibi.

Daha fazla bilgi için bkz.

Ayrıca bkz.

MFC'de Windows Yuvaları