📙
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. 版权与出版(Copyright and Distribution)
  • 2. 何谓 Socket
    • 2.1. 两种 Internet Sockets
    • 2.2. 底层漫谈与网路理论
  • 3. IP address丶结构与数据转换
    • 3.1. IPv4 与 IPv6
      • 31.1. Sub network (子网)
      • 3.1.2. Port Number(连接埠号码)
    • 3.2. Byte Order(字节的顺序)
    • 3.3. 数据结构
    • 3.4. IP address,Part II
      • 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()-"谢谢你调用 port 3490"
    • 5.7. send() 与 recv()- 宝贝,跟我说说话!
    • 5.8. sendto() 与 recvfrom()- 用 DGRAM 风格跟我说说话
    • 5.9. close() 与 shutdown()-从我面前消失吧!
    • 5.10. getpeername()-你是谁?
    • 5.11. gethostname()-我是誰?
  • 06-Client-Server 基础
    • 6.1. 简易的 Stream Server
    • 6.2. 简易的 Stream Client
    • 6.3. Datagram Sockets
  • 07-高等技术
    • 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()
    • close()
    • getaddrinfo(), freeaddrinfo(), gai_strerror()
    • gethostname()
    • gethostbyname(), gethostbyaddr()
    • getnameinfo()
    • getpeername()
    • errno
    • fcntl()
    • htons(), htonl(), ntohs(), ntohl()
    • inet_ntoa(), inet_aton(), inet_addr
    • inet_ntop(), inet_pton()
    • listen()
    • perror(), strerror()
    • poll()
    • recv(), recvfrom()
    • select()
    • setsockopt(), getsockopt()
    • send(), sendto()
    • shutdown()
    • socket()
    • 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 其实就是,在 Internet 世界中的每个人一般都已经同意的,如果你想要用两个 bytes 的十六进制数字来表示,比如说 b34f,你可以将它以 b34f 的顺序储存。很合理,而 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 而定。

大多数当你在打造数据包或填写数据结构时,你需要确认你的两个数字跟四个数字都是 Network Byte Order。只是如果你不知道本地端的 Host Byte Order,那该怎麽做呢?

好消息是你只需要假设 Host 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 节。

[14] http://en.wikipedia.org/wiki/Wilford_Brimley

如果我没特别强调的话,本文中的数值默认值是 Host Byte Order。

Previous3.1.2. Port Number(连接埠号码)Next3.3. 数据结构

Last updated 2 years ago