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 "big-Endian" standar jaringan. Tabel berikut menjelaskan istilah-istilah ini.
Pemesanan 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 byte-order untuk data yang Anda kirim dan terima melalui jaringan, tetapi ada situasi di mana Anda harus mengonversi pesanan byte.
Ketika Anda Harus Mengonversi Pesanan 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 jaringan.
Aplikasi server yang Anda komunikasikan bukan aplikasi MFC (dan Anda tidak memiliki kode sumber untuk itu). Ini memanggil konversi pesanan byte jika kedua komputer tidak berbagi urutan byte yang sama.
Ketika Anda Tidak Perlu Mengonversi Pesanan 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 menulis kedua ujung komunikasi: menggunakan MFC di kedua ujungnya. 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.
Catatan
Ketika ujung komunikasi lainnya bukan aplikasi MFC, Anda juga harus menghindari objek C++ streaming yang berasal dari CObject
arsip Anda karena penerima tidak akan dapat menanganinya. Lihat catatan di Soket Windows: Menggunakan Soket dengan Arsip.
Untuk informasi selengkapnya tentang pesanan byte, lihat spesifikasi Windows Sockets, yang tersedia di Windows SDK.
Contoh konversi Urutan Byte
Contoh berikut menunjukkan fungsi serialisasi untuk CSocket
objek yang menggunakan arsip. Ini juga mengilustrasikan menggunakan fungsi konversi urutan byte di 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 CArchive
objek dengan objek, dan CArchive
menggunakan urutan byte "little-Endian", yang berlawanan dengan CSocket
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 memanggil konversi data byte-order karena ada ketidakcocokan yang jelas antara urutan byte 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.
Fungsi Konversi Byte-Order Soket Windows
Function | Kegunaan |
---|---|
ntohs | Konversikan kuantitas 16-bit dari urutan byte jaringan ke urutan byte host (big-Endian ke little-Endian). |
ntohl | Konversikan kuantitas 32-bit dari urutan byte jaringan ke urutan byte host (big-Endian ke little-Endian). |
Htons | Konversikan kuantitas 16-bit dari urutan byte host ke urutan byte jaringan (little-Endian ke big-Endian). |
Htonl | Mengonversi kuantitas 32-bit dari urutan byte host ke 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: