3.2 字節序
國王命令!只有兩種字節序,他們是Lame 和Magnificent!
我開玩笑, 但事實就是這樣。J
事實上計算機存儲分為兩種:大端(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 toLong 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—seestruct in6_addr for IPv6)
// Internetaddress (a structure for historical reasons)
struct in_addr {
uint32_t s_addr; // that’s a 32-bit int (4 bytes)
};
它曾經是個最壞的聯合,但是現在那些日子過去了。如果你聲明 "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]; // IPv6address
}; www.2cto.com
我們看另外一個簡單的結構,struct sockaddr_storage他同時可以在IPv4和IPv6中使用。
其中ss_family字段請看AF_INET或者AF_INET6(IPv4 orIPv6)。映射的結構是struct sockaddr_in or struct sockaddr_in6。
摘自 xiaobin_HLJ80的專欄