Bagikan melalui


Windows Sockets: Pengurutan Byte

Artikel ini dan dua artikel pendamping menjelaskan beberapa masalah dalam pemrograman Windows Sockets. Artikel ini membahas urutan byte. Masalah lain tercakup dalam artikel: Windows Sockets: Blocking dan Windows Sockets: Mengonversi String.

Jika Anda menggunakan atau berasal dari kelas CAsyncSocket, Anda harus mengelola masalah ini sendiri. Jika Anda menggunakan atau berasal dari CSocket kelas, MFC mengelolanya untuk Anda.

Urutan Byte

Arsitektur komputer yang berbeda terkadang menyimpan data menggunakan pesanan byte yang berbeda. Misalnya, mesin berbasis Intel menyimpan data dalam urutan terbalik mesin Macintosh (Motorola). Urutan byte Intel, yang disebut "little-Endian," juga merupakan kebalikan dari urutan standar jaringan "big-Endian". Tabel berikut menjelaskan istilah-istilah ini.

Pengurutan Byte Besar dan Little-Endian

Urutan byte Makna
Big-Endian Byte yang paling signifikan adalah di ujung kiri kata.
Little-Endian Byte yang paling signifikan adalah di ujung kanan kata.

Biasanya, Anda tidak perlu khawatir tentang konversi urutan byte untuk data yang Anda kirim dan terima melalui jaringan, tetapi ada situasi di mana Anda harus mengonversi urutan byte.

Ketika Anda Harus Mengonversi Urutan Byte

Anda perlu mengonversi pesanan byte dalam situasi berikut:

  • Anda meneruskan informasi yang perlu ditafsirkan oleh jaringan, dibandingkan dengan data yang Anda kirim ke komputer lain. Misalnya, Anda mungkin meneruskan port dan alamat, yang harus dipahami oleh jaringan.

  • Aplikasi server yang Anda komunikasikan bukan aplikasi MFC (dan Anda tidak memiliki kode sumber untuk itu). Hal ini memerlukan konversi pengurutan byte jika kedua komputer tidak berbagi pengurutan byte yang sama.

Ketika Anda Tidak Perlu Mengonversi Urutan Byte

Anda dapat menghindari pekerjaan mengonversi pesanan byte dalam situasi berikut:

  • Mesin di kedua ujungnya dapat setuju untuk tidak menukar byte, dan kedua mesin menggunakan urutan byte yang sama.

  • Server yang berkomunikasi dengan Anda adalah aplikasi MFC.

  • Anda memiliki kode sumber untuk server yang berkomunikasi dengan Anda, sehingga Anda dapat mengetahui secara eksplisit apakah Anda harus mengonversi pesanan byte atau tidak.

  • Anda dapat memindahkan server ke MFC. Ini cukup mudah dilakukan, dan hasilnya biasanya lebih kecil, kode yang lebih cepat.

Bekerja dengan CAsyncSocket, Anda harus mengelola sendiri konversi urutan byte yang diperlukan. Windows Sockets menstandarkan model urutan byte "big-Endian" dan menyediakan fungsi untuk mengonversi antara urutan ini dan lainnya. Namun, CArchive yang Anda gunakan dengan CSocket, menggunakan urutan sebaliknya ("little-Endian"), tetapi CArchive mengurus detail konversi byte-order untuk Anda. Dengan menggunakan urutan standar ini dalam aplikasi Anda, atau menggunakan fungsi konversi byte-order Sockets Windows, Anda dapat membuat kode Anda lebih portabel.

Kasus ideal untuk menggunakan soket MFC adalah ketika Anda merancang kedua ujung komunikasi dengan menggunakan MFC di keduanya. Jika Anda menulis aplikasi yang akan berkomunikasi dengan aplikasi non-MFC, seperti server FTP, Anda mungkin perlu mengelola byte-swapping sendiri sebelum Anda meneruskan data ke objek arsip, menggunakan rutinitas konversi Soket Windows ntohs, ntohl, htons, dan htonl. Contoh fungsi-fungsi ini yang digunakan dalam berkomunikasi dengan aplikasi non-MFC muncul nanti di artikel ini.

Nota

Ketika ujung komunikasi lainnya bukan aplikasi MFC, Anda juga harus menghindari mengirimkan objek C++ yang diturunkan dari CObject ke dalam arsip Anda karena penerima tidak akan dapat menanganinya. Lihat catatan di Soket Windows: Menggunakan Soket dengan Arsip.

Untuk informasi lebih lanjut tentang urutan byte, silakan lihat spesifikasi Windows Sockets yang tersedia di dalam Windows SDK.

Contoh Penggunaan Konversi Byte-Order

Contoh berikut menunjukkan fungsi serialisasi untuk CSocket objek yang menggunakan arsip. Ini juga menggambarkan cara menggunakan fungsi konversi urutan byte dalam Windows Sockets API.

Contoh ini menyajikan skenario di mana Anda menulis klien yang berkomunikasi dengan aplikasi server non-MFC yang anda tidak memiliki akses ke kode sumber. Dalam skenario ini, Anda harus berasumsi bahwa server non-MFC menggunakan urutan byte jaringan standar. Sebaliknya, aplikasi klien MFC Anda menggunakan objek CArchive dengan objek CSocket, dan CArchive menggunakan urutan byte "little-Endian", yang berlawanan dengan standar jaringan.

Misalkan server non-MFC yang Anda rencanakan untuk berkomunikasi memiliki protokol yang ditetapkan untuk paket pesan seperti berikut ini:

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

Dalam istilah MFC, ini akan dinyatakan sebagai berikut:

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

   void Serialize(CArchive &ar);
};

Di C++, struct pada dasarnya sama dengan kelas. Struktur Message dapat memiliki fungsi anggota, seperti fungsi anggota yang Serialize dinyatakan di atas. Fungsi Serialize anggota mungkin terlihat seperti ini:

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

Contoh ini memerlukan konversi urutan byte data dikarenakan adanya ketidakcocokan yang jelas antara urutan byte dari aplikasi server non-MFC di satu ujung dan CArchive yang digunakan dalam aplikasi klien MFC Anda di ujung lain. Contoh ini mengilustrasikan beberapa fungsi konversi urutan byte yang disediakan Windows Sockets. Tabel berikut ini menjelaskan fungsi-fungsi ini.

Windows Sockets Byte-Order Fungsi Konversi

Fungsi Tujuan
ntohs Ubah kuantitas 16-bit dari urutan byte jaringan ke urutan byte host (big-Endian menjadi little-Endian).
ntohl Ubah kuantitas 32-bit dari urutan byte jaringan ke urutan byte host (big-Endian ke little-Endian).
Htons Ubah kuantitas 16-bit dari urutan byte host ke urutan byte jaringan (little-Endian ke big-Endian).
Htonl Ubah kuantitas 32-bit dari urutan byte host menjadi urutan byte jaringan (little-Endian ke big-Endian).

Poin lain dari contoh ini adalah bahwa ketika aplikasi soket di ujung lain komunikasi adalah aplikasi non-MFC, Anda harus menghindari melakukan sesuatu seperti berikut:

ar << pMsg;

di mana pMsg adalah pointer ke objek C++ yang berasal dari kelas CObject. Ini akan mengirim informasi MFC tambahan yang terkait dengan objek dan server tidak akan memahaminya, seperti jika itu adalah aplikasi MFC.

Untuk informasi selengkapnya, lihat:

Lihat juga

Windows Sockets pada MFC