Unix Socket - Thứ tự Byte Mạng

Thật không may, không phải tất cả các máy tính đều lưu trữ các byte bao gồm một giá trị multibyte theo cùng một thứ tự. Hãy xem xét một Internet 16-bit được tạo thành từ 2 byte. Có hai cách để lưu trữ giá trị này.

  • Little Endian - Trong lược đồ này, byte bậc thấp được lưu trên địa chỉ bắt đầu (A) và byte bậc cao được lưu trên địa chỉ tiếp theo (A + 1).

  • Big Endian - Trong lược đồ này, byte bậc cao được lưu trên địa chỉ bắt đầu (A) và byte bậc thấp được lưu trên địa chỉ tiếp theo (A + 1).

Để cho phép các máy có các quy ước thứ tự byte khác nhau giao tiếp với nhau, các giao thức Internet chỉ định một quy ước thứ tự byte chuẩn cho dữ liệu được truyền qua mạng. Điều này được gọi là Thứ tự Byte Mạng.

Trong khi thiết lập kết nối cổng kết nối Internet, bạn phải đảm bảo rằng dữ liệu trong các thành viên sin_port và sin_addr của cấu trúc sockaddr_in được thể hiện theo Thứ tự Mạng Byte.

Chức năng đặt hàng theo byte

Quy trình chuyển đổi dữ liệu giữa đại diện nội bộ của máy chủ lưu trữ và Thứ tự Byte Mạng như sau:

Chức năng Sự miêu tả
htons () Máy chủ lưu trữ vào mạng ngắn
htonl () Lưu trữ trên mạng dài
ntohl () Mạng để lưu trữ dài
ntohs () Network to Host Short

Dưới đây liệt kê một số chi tiết hơn về các chức năng này -

  • unsigned short htons(unsigned short hostshort) - Hàm này chuyển đổi các đại lượng 16 bit (2 byte) từ thứ tự byte chủ sang thứ tự byte mạng.

  • unsigned long htonl(unsigned long hostlong) - Hàm này chuyển đổi các đại lượng 32 bit (4 byte) từ thứ tự byte chủ sang thứ tự byte mạng.

  • unsigned short ntohs(unsigned short netshort) - Hàm này chuyển đổi các đại lượng 16 bit (2 byte) từ thứ tự byte mạng sang thứ tự byte máy chủ.

  • unsigned long ntohl(unsigned long netlong) - Hàm này chuyển đổi số lượng 32 bit từ thứ tự byte mạng sang thứ tự byte máy chủ.

Các hàm này là macro và dẫn đến việc chèn mã nguồn chuyển đổi vào chương trình gọi. Trên các máy endian nhỏ, mã sẽ thay đổi các giá trị xung quanh thành thứ tự byte mạng. Trên các máy big-end, không có mã nào được chèn vì không cần mã; các hàm được định nghĩa là null.

Chương trình xác định thứ tự Byte máy chủ

Giữ mã sau trong tệp byteorder.c , sau đó biên dịch nó và chạy nó trên máy của bạn.

Trong ví dụ này, chúng tôi lưu trữ giá trị hai byte 0x0102 trong số nguyên ngắn và sau đó xem xét hai byte liên tiếp, c [0] (địa chỉ A) và c [1] (địa chỉ A + 1) để xác định byte đặt hàng.

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

Đầu ra do chương trình này tạo ra trên máy Pentium như sau:

$> gcc byteorder.c
$> ./a.out
little-endian
$>