Aracılığıyla paylaş


Windows Soketleri: 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üretirseniz, 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.

Büyük ve Little-Endian Bayt Sıralama

Bayt sıralaması Anlamı
Big-Endian En önemli bayt bir sözcüğün sol ucundadır.
Little-Endian 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şmadığında bayt sıralamalarının dönüştürülmesini gerektirir.

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 Sockets, "big-Endian" bayt sırası modelini standart hale getirir ve bu sıra ile diğer sıralar arasında dönüştürme fonksiyonları sunar. 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.

Uyarı

İ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 Soketleri: 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 Sockets belirtimi.

Byte-Order 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 CArchive nesnesini ve CSocket nesnesini kullanır ve CArchive "little-Endian" bayt sırasını, yani ağ standardının tersi olan sıra düzenini 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. Message yapısı, yukarıda belirtilen Serialize gibi üye fonksiyonlara sahip olabilir. Bu 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, MFC olmayan sunucu uygulamanızın bayt sıralaması ile MFC istemci uygulamanızda kullanılan arasındaki belirgin bir uyuşmazlık nedeniyle veri bayt sırasının dönüştürülmesi gerekir. Ö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 Sockets Byte-Order Dönüştürme Fonksiyonları

İşlev Amaç
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 değeri ağ bayt sırasından konak bayt sırasına 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 değeri ana bilgisayar bayt düzeninden ağ bayt düzenine (küçük-endian'dan büyük-endian'a) 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 bakınız:

Ayrıca bakınız

MFC'de Windows Sockets