📘
Beej's Guide to Network Programming 正體中文版
  • 簡介
  • 原著資訊
  • 譯者誌謝
  • 進階資料
  • 簡體中文版
  • 中文授權
  • 聯絡譯者
  • 1. 導讀
    • 1.1. 本書的讀者
    • 1.2. 平台與編譯器
    • 1.3. 官方網頁與書本
    • 1.4. Solaris/SunOS 程式設計師該注意的事
    • 1.5. Windows 程式設計師該注意的事
    • 1.6. 來信原則
    • 1.7. 鏡射站台(Mirroring)
    • 1.8. 譯者該注意的
    • 1.9. 版權與散佈
  • 2. 何謂 Socket
    • 2.1 兩種 Internet Sockets
    • 2.2 底層漫談與網路理論
  • 3. IP address、結構與資料轉換
    • 3.1. IPv4 與 IPv6
      • 3.1.1. Sub network (子網段)
      • 3.1.2. Port Number(連接埠號碼)
    • 3.2. Byte Order(位元組順序)
    • 3.3. 資料結構
    • 3.4. IP 位址,續集
      • 3.4.1 Private Network
  • 4. 從 IPv4 移植為 IPv6
  • 5. System call 或 Bust
    • 5.1. getaddrinfo()-準備開始!
    • 5.2. socket()-取得 File Descriptor!
    • 5.3. bind()- 我在哪個 port?
    • 5.4. connect(),嘿!你好。
    • 5.5. listen()-有人會呼叫我嗎?
    • 5.6. accept()- 謝謝你 call 3490 port
    • 5.7. send() 與 recv()- 寶貝,我們來聊天!
    • 5.8. sendto() 與 recvfrom()- 來點 DGRAM
    • 5.9. close() 與 shutdown()- 你消失吧!
    • 5.10. getpeername()-你是誰?
    • 5.11. gethostname()-我是誰?
  • 6. Client-Server 基礎
    • 6.1. 簡單的 Stream Server
    • 6.2. 簡單的 Stream Client
    • 6.3. Datagram Sockets
  • 7. 進階技術
    • 7.1. Blocking(阻塞)
    • 7.2. select():同步 I/O 多工
    • 7.3. 不完整傳送的後續處理
    • 7.4. Serialization:如何封裝資料
    • 7.5. 資料封裝
    • 7.6. 廣播封包:Hello World!
  • 8. 常見的問題
  • 9. Man 使用手冊
    • 9.1. accept()
    • 9.2. bind()
    • 9.3. connect()
    • 9.4. close()
    • 9.5. getaddrinfo(), freeaddrinfo(), gai_strerror()
    • 9.6. gethostname()
    • 9.7. gethostbyname(), gethostbyaddr()
    • 9.8. getnameinfo()
    • 9.9. getpeername()
    • 9.10. errno
    • 9.11. fcntl()
    • 9.12. htons(), htonl(), ntohs(), ntohl()
    • 9.13. inet_ntoa(), inet_aton(), inet_addr
    • 9.14. inet_ntop(), inet_pton()
    • 9.15. listen()
    • 9.16. perror(), strerror()
    • 9.17. poll()
    • 9.18. recv(), recvfrom()
    • 9.19. select()
    • 9.20. setsockopt(), getsockopt()
    • 9.21. send(), sendto()
    • 9.22. shutdown()
    • 9.23. socket()
    • 9.24. struct sockaddr and pals
  • 10. 參考資料
    • 10.1. 書籍
    • 10.2. 網站參考資料
    • 10.3. RFC
  • 11. 原著誌謝
Powered by GitBook
On this page
Edit on GitHub
  1. 3. IP address、結構與資料轉換

3.2. Byte Order(位元組順序)

一直都以為有兩種 byte orderings,現在才知道,其實只有一種。

開玩笑的,但是其中一個的確比較受推崇 :-)

這真的不容易解釋,所以我只能胡扯:你的電腦可能背著你用相反的順序來儲存 bytes。我知道!以前沒人跟你說過。

Byte Order 其實就是,若你想要用兩個 bytes 的十六進制數字來表示資料,比如說 b34f,你可以將它以 b34f 的順序儲存,這件事在 Internet 世界的每個人一般都可以同意。這很合理,而且 Wilford Brimley [14] 也會跟你說,這麼做是對的。由於這個數字是先儲存比較大的那一邊(big end),所以稱為 Big-Endian。

不幸的是,世界上的電腦那麼多,而 Intel 或 Intel 相容處理器就將 bytes 反過來儲存,所以 b34f 存在記憶體中的順序就是 4fb3,這樣的儲存方式稱為 Little-Endian。

不過,請等等。我還沒解釋名詞哩!

照理說,Big-Endian 又稱為 Network Byte Order,因為這個順序與我們網路類型順序一樣。

你的電腦會以 Host Byte Order 儲存數字,如果是 Intel 80x86,Host Byte Order 是 Little-Endian;若是 Motorola 68k,則 Host Byte Order 是 Big-Endian;若是 PowerPC,Host Byte Order 就是 … 恩,這要看你的 PowerPC 而定。

大多數當你在打造封包或填寫資料結構時,你需要確認你的 port number 跟 IP address 都是 Network Byte Order。只是如果你不知道本機的 Host Byte Order,那該怎麼做呢?

好消息是,我們可以直接假設,全部電腦的 Host Byte Order 都不是 Network Byte Order,然後每次都用函式將值轉換為 Network Byte Order。如果有必要,函式會發動魔法般的轉換,而這個方式會讓你的程式碼能更方便地移植到不同 endian 的機器。

你可以轉換兩種型別的數值:short[兩個 bytes]與 long[四個 bytes]。這些函式也可以用在 unsigned 變數。比如說,你想要將 short 從 Host Byte Order 轉換為 Network Byte Order, 'h' 代表 "host", 'n' 代表 "network",而 's' 代表 "short",所以是:h-to-n-s,或者 htons()[讀做:"Host to Network Short"]。

這真是太簡單了…

你可以用任何你想要的方式來組合 'n'、 'h'、's' 與 'l',不過別用太蠢的組合,比如:沒有這樣的函式 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

基本上,你需要在送出封包以前將數值轉換為 Network Byte Order,並在收到封包之後將數值轉回 Host Byte Order。

抱歉,我不知道 64-bit 的差異,如果你想要處理浮點數的話,可以參考 7.4 節。

如果我沒特別強調的話,本文中的數值預設是視為 Host Byte Order。

Previous3.1.2. Port Number(連接埠號碼)Next3.3. 資料結構

Last updated 2 years ago

[14]

http://en.wikipedia.org/wiki/Wilford_Brimley