Unix Socket - คำสั่งไบต์เครือข่าย
ขออภัยไม่ใช่ว่าคอมพิวเตอร์ทุกเครื่องจะเก็บไบต์ที่ประกอบด้วยค่าหลายไบต์ในลำดับเดียวกัน พิจารณาอินเทอร์เน็ต 16 บิตที่ประกอบด้วย 2 ไบต์ มีสองวิธีในการจัดเก็บค่านี้
Little Endian - ในรูปแบบนี้ไบต์ลำดับต่ำจะถูกเก็บไว้ในที่อยู่เริ่มต้น (A) และไบต์ลำดับสูงจะถูกเก็บไว้ในที่อยู่ถัดไป (A + 1)
Big Endian - ในรูปแบบนี้ไบต์ลำดับสูงจะถูกเก็บไว้ในที่อยู่เริ่มต้น (A) และไบต์ลำดับต่ำจะถูกเก็บไว้ในที่อยู่ถัดไป (A + 1)
เพื่อให้เครื่องที่มีระเบียบการสั่งซื้อไบต์ที่แตกต่างกันสามารถสื่อสารกันได้อินเทอร์เน็ตโปรโตคอลจะระบุรูปแบบการสั่งซื้อไบต์มาตรฐานสำหรับข้อมูลที่ส่งผ่านเครือข่าย สิ่งนี้เรียกว่า Network Byte Order
ในขณะที่สร้างการเชื่อมต่อซ็อกเก็ตอินเทอร์เน็ตคุณต้องตรวจสอบให้แน่ใจว่าข้อมูลในสมาชิก sin_port และ sin_addr ของโครงสร้าง sockaddr_in แสดงในลำดับไบต์ของเครือข่าย
ฟังก์ชันการสั่งซื้อไบต์
กิจวัตรในการแปลงข้อมูลระหว่างการเป็นตัวแทนภายในของโฮสต์และลำดับไบต์ของเครือข่ายมีดังนี้ -
ฟังก์ชัน | คำอธิบาย |
---|---|
htons () | โฮสต์ไปยังเครือข่ายสั้น |
htonl () | โฮสต์ไปยังเครือข่ายแบบยาว |
ntohl () | เครือข่ายโฮสต์ยาว |
ntohs () | เครือข่ายไปยังโฮสต์สั้น |
ด้านล่างนี้เป็นรายละเอียดเพิ่มเติมเกี่ยวกับฟังก์ชันเหล่านี้ -
unsigned short htons(unsigned short hostshort) - ฟังก์ชันนี้จะแปลงปริมาณ 16 บิต (2 ไบต์) จากคำสั่งไบต์ของโฮสต์เป็นลำดับไบต์ของเครือข่าย
unsigned long htonl(unsigned long hostlong) - ฟังก์ชันนี้จะแปลงปริมาณ 32 บิต (4 ไบต์) จากคำสั่งไบต์ของโฮสต์เป็นลำดับไบต์ของเครือข่าย
unsigned short ntohs(unsigned short netshort) - ฟังก์ชันนี้จะแปลงปริมาณ 16 บิต (2 ไบต์) จากคำสั่งไบต์เครือข่ายเป็นคำสั่งไบต์ของโฮสต์
unsigned long ntohl(unsigned long netlong) - ฟังก์ชันนี้จะแปลงปริมาณ 32 บิตจากคำสั่งไบต์เครือข่ายเป็นคำสั่งไบต์ของโฮสต์
ฟังก์ชันเหล่านี้เป็นมาโครและส่งผลให้มีการแทรกซอร์สโค้ดการแปลงลงในโปรแกรมการโทร ในเครื่องเล็ก ๆ น้อย ๆ รหัสจะเปลี่ยนค่ารอบเป็นลำดับไบต์เครือข่าย สำหรับเครื่อง big-endian จะไม่มีการใส่รหัสเนื่องจากไม่จำเป็นต้องใช้ ฟังก์ชันถูกกำหนดให้เป็นโมฆะ
โปรแกรมเพื่อกำหนดลำดับไบต์ของโฮสต์
เก็บรหัสต่อไปนี้ไว้ในไฟล์byteorder.cจากนั้นคอมไพล์แล้วรันบนเครื่องของคุณ
ในตัวอย่างนี้เราเก็บค่า 0x0102 สองไบต์ไว้ในจำนวนเต็มสั้น ๆ จากนั้นดูที่สองไบต์ที่ต่อเนื่องกัน c [0] (ที่อยู่ A) และ c [1] (ที่อยู่ A + 1) เพื่อกำหนดไบต์ ใบสั่ง.
#include <stdio.h>
int main(int argc, char **argv) {
union {
short s;
char c[sizeof(short)];
}un;
un.s = 0x0102;
if (sizeof(short) == 2) {
if (un.c[0] == 1 && un.c[1] == 2)
printf("big-endian\n");
else if (un.c[0] == 2 && un.c[1] == 1)
printf("little-endian\n");
else
printf("unknown\n");
}
else {
printf("sizeof(short) = %d\n", sizeof(short));
}
exit(0);
}
ผลลัพธ์ที่สร้างโดยโปรแกรมนี้บนเครื่อง Pentium มีดังนี้ -
$> gcc byteorder.c
$> ./a.out
little-endian
$>