摘要
- Sun Microsystems 的 RFC 1014 要求编码项占用四字节的整数倍。可变长字符串先写四字节长度,再写字符,末尾补零直到下一条四字节边界。
- RFC 自带的文件实例中,
sillyprog的名字有九字节,后面补三个零;文件类型从偏移量 16 开始。长度负责说清名字有多长,填充负责把下一项放到双方都找得到的位置。
Sun Microsystems 在 RFC 的最后安排了一位叫 john 的用户,让他保存一个 Lisp 程序 sillyprog。这个名字看着像程序员午饭前想出的笑话,编码却一板一眼:先用四个字节写长度 9,再写九个字母,最后补三个零。于是文件类型字段从偏移量 16 开始。三个零没有给程序添名字,它们是在给后面的字段清场。
1987 年,Sun 工作站、VAX、IBM PC 和 Cray 都可能参与数据交换。机器的本地内存布局各有脾气,一台机器的结构体直接搬到另一台上,接收方很难只凭字节猜对每个值。XDR,即外部数据表示,给交换的数据另立一套描述和编码办法。RFC 1014 说 Sun RPC 和 NFS 用它描述数据。它假定八位字节可在设备间保留原义,并让编码项按四字节一组排队。
整数本来就是 32 位,刚好站满一组。文件名却不听安排,九个字母占了两组半。XDR 不去改名,只在末尾添零,把第三组补齐。长度字段记录的仍是 9,表示真正属于名字的九个字节;整个名字在数据流里占十二个字节。发送端多写几笔,接收端就知道下一个字段从哪一组开始。这个账非常小,也非常具体。
RFC 的十六进制表格可以逐位核对。偏移量 0 到 3 是长度 9;从 4 到 12 是 sillyprog 的九个字符;13、14、15 是填充零;16 开始是文件类型 EXEC,数值 2。把填充零当作名字,读出的名字会变。读完九个字符就立即找下一字段,又会提前三个位置。两台机器能否对同一个文件得出同一份解释,关键就在这三个没人愿意多看的零上。
例子还继续向前走。EXEC 选中了一个解释器字段,内容是 lisp:先写长度 4,再写四个字符。所有者 john 也按这种方式编码。程序数据 (quit) 有六个字节,前面有长度 6,后面补两个零。每个字段的自然长度不同,但接收端反复做同一件事:读长度、读内容、越过填充,再读下一项。节拍一旦定好,内容便可以长短不一。
字符串和不透明数据在这里也有分工。RFC 里的字符串由 ASCII 字节组成;不透明数据则保留字节内容,XDR 不替应用解释。两者都可以声明长度上限,超过上限便是编码错误。长度字段因此既告诉读者何处结束,也给检查边界一个数。填充零的职责不同:让下一项从整齐的四字节边界开始。把两种职责混在一起,解析器就会把座位号当乘客名单。
XDR 还用类型描述规定字段的先后。例如文件类型不是装饰品:它决定后面该读哪个分支。EXEC 后接解释器,别的文件类型可以带不同内容。接收方依照共享的描述读数据,而不是揣摩发送方编译器如何摆放内存。这正是四字节规则的用处:它让下一次类型判断发生在可计算的位置。
补零当然占空间。九字节名字要交出三个额外字节,六字节数据要交出两个。RFC 没用一张宏大的性能图掩盖这笔小账,而是把每个偏移量摆出来。读者从 0 数到 16,马上知道代价买来了什么:下一字段按约定落座。sillyprog 这个文件名也因此十分合适。程序可以胡闹,字节座次不能。
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance





