3.2 字節序(Byte Order)

原文:https://beej.us/guide/bgnet/html/#byte-order

 

3.2 字節序

國王命令!只有兩種字節序,他們是Lame 和Magnificent!

我開玩笑, 但事實就是這樣。

事實上計算機存儲分爲兩種:大端(Big-Endian)和小端(Little-Endian)。

不同架構的計算機有不同的主機序,比如Intel80x80的主機字節序是小端。摩托羅拉的68K主機序是大端。還有PowerPC的主機序是…等等!

那我們怎麼封裝我們的網絡字節序呢?

好消息!你不用考慮這些主機字節序細節。我們使用一些函數來處理這些。

好。我們兩種類型來轉換他們:short(兩字節)和long(四字節)。他們都是無符號的。如果你要主機序爲short的,我們使用htons()函數。h代表host,n代表network,s表示short。(讀作:Host to Network Short)

這多麼簡單呀…

你能用任何他們的組合(n, h, s),但是你不能使用stolh()函數(Short to Long Host)~~

下面是一些常用的函數:

htons()          host to network short

htonl()          host to network long

ntohs()          network to host short

ntohl()          network to host long

 

3.3 結構體

       終於談到編程了。在這章,我將談到被套接字用到的各種數據類型。 因爲它們中的一些內容很重要了。

       首先是簡單的一個:socket描述符。它是下面的類型:

       int

       僅僅是一個常見的 int。

       從現在起,事情變得不可思議了,而你所需做的就是繼續看下去。注意這樣的事實:有兩種字節排列順序:重要的字節 (有時叫"octet",即八位位組) 在前面,或者不重要的字節在前面。前一種叫“網絡字節順序 (Network Byte Order)”。有些機器在內部是按照這個順序儲存數據,而另外一些則不然。當我說某數據必須按照 NBO 順序,那麼你要調用函數(例如 htons() )來將它從本機字節順序 (Host Byte Order) 轉換過來。如果我沒有 提到 NBO, 那麼就讓它保持本機字節順序。

       我的第一個結構(在這個技術手冊TM中)--struct addrinfo.。這個結構爲許多類型的套接字儲存套接字提供了首要的信息:

       我們可以使用getaddrinfo()函數獲得一個指向該結構的指針。

       使用此函數是爲了維護IPv4到IPv6的指南。

       然而,我們實際使用的結構是structsockaddr.

struct sockaddr {
    unsigned short              sa_family;           //address family, AF_xxx

    char                        sa_data[14]          // 14 bytes of protocol address
};

       sa_family在IPv4是AF_INET,而IPv6是AF_INET6.

       sa_data 包含地址(IP)和端口(經過處理的)。

       具體到程序員使用的是structsockaddr_in結構。這個結構是直接映射到struct sockaddr的。

注意sin_zero可以使用bzero()函數設置。(原文爲memset())

       sin_port必須使用htons()!

其中struct in_addr的結構聲明:

    // (IPv4 only--see struct sockaddr_in6 for IPv6)
    
    struct sockaddr_in {
        short int          sin_family;  // Address family, AF_INET
        unsigned short int sin_port;    // Port number
        struct in_addr     sin_addr;    // Internet address
        unsigned char      sin_zero[8]; // Same size as struct sockaddr
    };

       它曾經是個最壞的聯合,但是現在那些日子過去了。如果你聲明 "ina" 是數據結構struct sockaddr_in 的實例,那麼 "ina.sin_addr.s_addr" 就存儲4字節的 IP 地址(使用網絡字節順序)。如果你不幸的系統使用的還是恐怖的struct in_addr ,你還是可以放心4字節的 IP 地址並且和上面我說的一樣(這是因爲使用了“#define”。)

       那關於IPv6的呢?下面就是:

 

struct in6_addr {
    unsigned char s6_addr[16];        // IP v6 address
};

       我們看另外一個簡單的結構,struct sockaddr_storage他同時可以在IPv4和IPv6中使用。

其中ss_family字段請看AF_INET或者AF_INET6(IPv4 or IPv6)。映射的結構是struct sockaddr_in or struct sockaddr_in6。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章