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
$>