7.3 协议
当各种各样的编程语言动辄有着复杂的语法, 并且使用了许多多字母保留字(这使用它们易于被人类程序员明白); 数据通信的语言则倾向于简洁。它们经常使用一个个 二进制位,而不是多字节单词。 这有一个很令人信服的理由: 数据在你的计算机 内部 可以以光速高速行进, 而在计算机之间传递数据时, 速度却会慢得多。
因为数据通信中使用的语言很简洁,我们通常把它们称为 协议,而不是语言。
当数据从一台计算机行进到另一台时,它一般使用超过一种协议。 这些协议是 分层次的。 数据可以与一头洋葱的芯类比:只有你剥开几层“表皮” 后才可取得数据。这最好用一张图说明:
在这个例子中,我们尝试从用以太网连着的网页上获取一幅图像。
图像由原始数据组成,那是一个我们的软件能够处理的(转换为一幅 图片并显示在我们的显示器上)红绿蓝值序列。
唉,我们的软件无法知道原始数据是如何组织的:那是一个 红绿蓝值序列,还是一个灰度序列,或者可能是 CMYK编码的色彩?数据是表现为8位离散值,还是16位大小, 或是4位?图像由多少行和列组织?有的像素应当是透明的吗?
我想你得到了图片……
为了统一我们的软件处理原始数据的方式,数据被编码为 PNG文件。那也可以是 GIF,或JPEG文件, 不一定只是PNG文件。
于是PNG就是一种协议。
对于这一点,我可以听见你的喊声: “不,那不是!那是一种文件格式! ”
好,那当然是一种文件格式。但从数据通信的方面说, 一种文件格式也是一种协议: 文件结构是一种语言,而且还是一种简洁的语言, 与我们的进程通信,确定数据如何被组织。 因此,那是一种协议。
唉,假如我们接收到的只有PNG文件, 我们的软件将要面对一个严峻的问题:将如何知道数据代表一幅图像, 而不是一些文本、或可能是一段声音,或者这些都不是?其次,将如何 知道图像是PNG格式的,而不是 GIF,或是JPEG, 或是其它图像格式?
要取得那些信息,我们使用另一种协议: HTTP。这种协议能告诉我们数据确实代表一幅图像, 并且图像使用PNG协议。它也能告诉我们其它一些东西, 不过还是让我们把注意力停留在协议层次这里吧。
至此,我们有一些数据被包裹在PNG 协议中,而后又被包裹在HTTP协议中。 我们如何从服务器上取得它?
通过在以太网上使用TCP/IP,这就是方法。 实际上,有比三种更多的协议。我不再继续深入了,我现在开始说说以太网, 只因为这样更容易解释其余的问题。
以太网是一种有趣的系统,它将计算机连接在一个 局域网 (local area network,LAN)中。 每台计算机有一个网络接口卡(中文简称“网卡”) (network interface card,NIC)。 每个网卡有一个唯一的48位标识,称为它的 地址。世界上没有两块 网卡会有相同的地址。
这些网卡彼此相连。 一旦一台计算机要与在同一以太网局域网中的另一台计算机 通信时,就在网络上发送一条消息。每个网卡都会看见 这条消息。但是作为以太网协议的一部分, 数据包含目的网卡的地址(还有其它内容)。所以, 在所有网卡中只有一个会注意那条消息,其余的则会忽略。
但并非所有的计算机都被连接在同一网络上。 因为我们在我们的以太网上所接收到的数据并不意味着那一定源自于我们的局域网。 可能有来自其它通过Internet 与我们自己的网络相连的网络的数据来我们面前。
在Internet上传送的所有数据都使用IP。 IP表示网间协议 (Internet Protocol)。它的基本功能是让我们知道 世界上的数据从哪里到来,应该会到哪里去。它并不 保证我们一定会接收到数据, 只保证假如我们接收到数据时会知道它从哪里来。
甚至即使我们接收到数据,IP 也不保证我们会按照其它计算机发送数据段的顺序接收到这些数据段。 举个例子,我们接收到图像的中心部分可能在接收到左上角之前, 又可能在接收到右下角之后。
是TCP (Transmission Control Protocol,传输控制协议) 要求发送方重发丢失的数据,并且把数据都排成正确的顺序。
总结起来,一台计算机与另一台计算机通信一幅图像的样子需要 五个不同的协议。我们接收到的数据被包裹进 PNG协议,这又被包裹进 HTTP协议,而后又被包裹进 TCP协议,再后来又被包裹进 IP协议,最后被包裹进 Ethernet协议。
欧,顺便说一下,可能有几个其它的协议包含在那其中的某个位置。 例如,如果我们的局域网通过电话呼叫接入 Internet,就会在调制解调器上使用PPP协议, 而调制解调器还可能使用一个(或多个)调制解调器协议, 等等,等等,等等……
到现在为止作为一个开发者你应该问: “我应该如何掌握它们全部? ”
你是幸运的,你不必掌握它们全部。 你只要掌握其中的一部分,而不是全部。 尤其你不需要担心物理连接(在我们的情形中是以太网和 可能的PPP等)。你也不需要掌握网间协议, 或是传输控制协议。
换句话说,你不必为从其它计算机接收数据做所有的事情。 好,你又要问要做什么, 事实上就像打开一个文件一样简单。
一旦你收到数据,就需要你指出如何处理。 在我们的情形中,你需要明白HTTP协议和 PNG文件结构。
以此类推,所有联网协议变成一个灰色区域: 并非因为我们不明白它们如何工作,而是因为我们不必关心它们。 套接字接口为我们照管这些灰色区域:
我们只需要明白告诉我们如何理解数据的协议, 而不是如何从其它进程接收数据, 也不是如何向其它进程发送数据。