Networks (网络)
Linux 和网络几乎是同义词。实际上 Linux 是 Internet 或 WWW 的产物。它的开发者和用户使用 web 交换信息、想法、代码而 Linux 自身也常用于支持一些组织的联网需求。本章描述了 Linux 如何支持统称为 TCP/IP 的网络协议。
TCP/IP 协议设计用来支持连接在 ARPANET 上的计算机之间的通讯。 ARPANET 是美国政府投资的一个美国的研究网络。 ARPANET 是一些网络概念的先驱,例如报文交换和协议分层,让一种协议利用其它协议提供的服务。 ARPANET 于 1988 年退出,但是它的后继者( NSF NET 和 Internet )发展的甚至更大。现在所知的 World Wide Web 是在 ARPANET 中发展的,它本身也是由 TCP/IP 协议支持的。 Unix 在 ARPANET 上大量使用,第一个发布的网络版的 Unix 是 4.3BSD 。 Linux 的网络实现是基于 4.3BSD 的模型,它支持 BSD socket (和一些扩展)和全系列的 TCP/IP 网络功能。选择这种编程接口是因为它的流行程度,而且可以帮助程序在 Linux 和其它 Unix 平台之间移植。
10.1 An Overview of TCP/IP Networking ( TCP/IP 网络概览)
本节为 TCP/IP 网络的主要原理给出了一个概览。这并不是一个详尽的描述。要更详细的描述,阅读第 10 本参考书(附录)。
在一个 IP 网络中,每一个机器都分配一个 IP 地址,这是一个 32 位的数字,唯一标识这一台机器。 WWW 是一个非常巨大、不断增长的 IP 网络,每一个连接在上面的机器都分配了一个独一无二的 IP 地址。 IP 地址用点分隔的四个数字表示,例如, 16.42.0.9 。 IP 地址实际上分为两个部分:网络地址和主机地址。这些地址的大小(尺寸)可能不同(有几类 IP 地址),以 16.42.0.9 为例,网络地址是 16.42 ,主机地址是 0.9 。主机地址可以进一步划分成为子网( subnetwork )和主机地址。再次以 16.42.0.9 为例,子网地址可以是 16.42.0 ,主机地址为 16.42.0.9 。对于 IP 地址进行进一步划分允许各个组织划分它们自己的网络。例如,假设 16.42 是 ACME 计算机公司的网络地址, 16.42.0 可以是子网 0 , 16.42.1 可以是子网 1 。这些子网可以在分离的大楼里,也许通过电话专线或者甚至通过微波连接。 IP 地址由网络管理员分配,使用 IP 子网是分散网络管理任务的一个好办法。 IP 子网的管理员可以自由地分配他们自己子网内的 IP 地址。
但是,通常 IP 地址难于记忆,而名字更容易记忆。 Linux.acme.com 比 16.42.0.9 更好记。必须使用一种机制把网络名字转换为 IP 地址。这些名字可以静态地存在 /etc/hosts 文件中或者让 Linux 询问一个分布式命名服务器( Distributed Name Server DNS )来解析名字。这种情况下,本地主机必须知道一个或多个 DNS 服务器的 IP 地址,在 /etc/resolv.conf 中指定。
不管什么时候你连接另外一台机器的时候,比如读取一个 web page ,都要使用它的 IP 地址和那台机器交换数据。这种数据包括在 IP 报文( packet )中,每一个报文都有一个 IP 头(包括源和目标机器的 IP 地址,一个校验和和其它有用的信息。这个校验和是从 IP 报文的数据中得到的,可以让 IP 报文的接收者判断传输过程中 IP 报文是否损坏(可能是一个噪音很大的电话线)。应用程序传输的数据可能被分解成容易处理的更小的报文。 IP 数据报文的大小依赖于连接的介质而变化:以太网报文通常大于 PPP 报文。目标主机必须重新装配这些数据报文,然后才能交给接收程序。如果你通过一个相当慢的串行连接访问一个包括大量图形图像的 web 页,你就可以用图形的方式看出数据的分解和重组。
连接在同一个 IP 子网的主机可以互相直接发送 IP 报文,而其它的 IP 报文必须通过一个特殊的主机(网关)发送。网关(或路由器)连接在多于一个子网上,它们会把一个子网上接收的 IP 报文重新发送到另一个子网。例如,如果子网 16.42.1.0 和 16.42.0.0 通过一个网关连接,那么所有从子网 0 发送到子网 1 的报文必须先发送到网关,这样才能转发。本地的主机建立一个路由表,让它可以把要转发的 IP 报文发送到正确的机器。对于每一个 IP 目标,在路由表中都有一个条目,告诉 Linux 要到达目标需要先把 IP 报文发送到那一台主机。这些路由表是动态的,而且当应用程序使用网络和网络拓扑变化的时候不断改变。
IP 协议是传输层协议,被其他协议使用,携带它们的数据。传输控制协议( TCP )是一个可靠的端到端的协议,使用 IP 传送和接收它的报文。象 IP 报文有自己的头一样, TCP 也有自己的头。 TCP 是一个面向连接的协议,两个网络应用程序通过一个虚拟的连接连接在一起,甚至它们中间可能会有许多子网、网关和路由器。 TCP 在两个应用程序之间可靠地传送和接收数据,并且保证不会有丢失和重复的数据。当 TCP 使用 IP 传送它的报文的时候,在 IP 报文中包含的数据就是 TCP 报文自身。每一个通讯的主机的 IP 层负责传送和接收 IP 报文。用户数据报协议( UDP )也使用 IP 层传送它的报文,但是不象 TCP , UDP 不是一个可靠的协议,它只提供数据报服务。其它协议也可以使用 IP 意味着当接收到 IP 报文,接收的 IP 层必须知道把这个 IP 报文中包含的数据交给哪一个上层协议。为此,每一个 IP 报文的头都有一个字节,包含一个协议标识符。当 TCP 请求 IP 层传输一个 IP 报文的时候 IP 报文的头就说明它包含一个 TCP 报文。接收的 IP 层,使用这个协议标识符来决定把接收到的数据向上传递给哪一个协议,在这种情况下,是 TCP 层。当应用程序通过 TCP/IP 通讯的时候,它们不但必须指定目标的 IP 地址,也要指定目标应用程序的端口( port )地址。一个端口地址唯一标识一个应用程序,标准的网络应用程序使用标准的端口地址:例如 web 服务器使用端口 80 。这些已经注册的端口地址可以在 /etc/services 中查到。
协议分层不仅仅停留在 TCP 、 UDP 和 IP 。 IP 协议本身使用许多不同的物理介质和其它 IP 主机传输 IP 报文。这些介质自己也可能增加它们自己的协议头。这样的例子有以太网层、 PPP 和 SLIP 。一个以太网允许许多主机同时连接在一个物理电缆上。每一个传送的以太帧可以被所有连接的主机看到,所以每一个以太网设备都有一个独一无二的地址。每一个传送到那个地址的以太网帧会被那个地址的主机接收,而被连接到这个网络的其它主机忽略掉。这个独一无二的地址当每一个以太网设备制造的时候内建在设备里边,通常保存在以太网卡的 SROM 中。以太地址由 6 个字节长,例如,可能是 08-00-2b-00-49-4A 。一些以太网地址保留用于多点广播,用这种目标地址发送的以太网帧会被网络上的所有的主机接收。因为以太网帧中可能运载许多不同的协议(作为数据),和 IP 报文一样,它们的头中都包含一个协议标识符。这样以太网层可以正确地接收 IP 报文并把数据传输到 IP 层。
为了通过多种连接协议,例如通过以太网来传输 IP 报文, IP 层必须找出这个 IP 主机的以太网地址。这是因为 IP 地址只是一个寻址的概念,以太网设备自己有自己的物理地址。 IP 地址可以由网络管理员根据需要分配和再分配,而网络硬件则只响应具有它自己物理地址的以太网帧,或者特殊的多点广播地址(所有的机器都必须接收)。 Linux 使用地址解析协议( ARP )让机器把 IP 地址转换成真实的硬件地址例如以太网地址。为了得到一个 IP 地址所联系的硬件地址,一个主机会发送一个 ARP 请求包,包含它希望转换的 IP 地址,发送到一个多点广播地址,让网络上所有的点都可以收到。具有这个 IP 地址的目标主机用一个 ARP 回应来应答,这中间包括了它的物理硬件地址。 APR 不仅仅限制在以太网设备,它也可以解析其它物理介质的 IP 地址,例如 FDDI 。不能进行 ARP 的设备会有标记,这样 Linux 就不需要试图对它们进行 ARP 。也有一个相反的功能,反向 ARP ,或 RARP ,把物理地址转换到 IP 地址。这用于网关,回应对于代表远端网络的 IP 地址的 ARP 请求。
10.2 The Linux TCP/IP Networking Layers ( Linux TCP/IP 网络分层)
象网络协议一样,图 10.2 显示了 Linux 对于 internet 协议地址族的实现就好像一系列连接的软件层。 BSD socket 由只和 BSD socket 相关的通用的 socket 管理软件来支持。支持这些的是 INET socket 层,它管理以 IP 为基础的协议 TCP 和 UDP 的通讯端点。 UDP 是一个无连接的协议,而 TCP 是一个可靠的端到端的协议。当传送 UDP 报文的时候, Linux 不知道也不关心它们是否安全到达目的地。 TCP 报文进行了编号, TCP 连接的每一端都要确保传送的数据正确地接收到。 IP 层包括了网际协议( Internet Protocol )的代码实现。这种代码在传送的数据前增加 IP 头,而且知道如何把进来的 IP 报文转送到 TCP 或者 UDP 层。在 IP 层之下,支持 Linux 联网的是网络设备,例如 PPP 和以太网。网络设备并非总是表现为物理设备:其中一些比如 loopback 设备只是纯粹的软件设备。不象标准的 Linux 设备用 mknod 命令创建,网络设备只有在底层的软件找到并且初始化它们之后才出现。你只有在建立俄一个包含恰当的以太望设备驱动程序的核心之后你才能看到设备文件 /dev/eth0 。 ARP 协议位于 IP 层和支持 ARP 的协议之间。
这是一个通用的接口,不仅仅支持多种形式的联网,也是一种进程间通讯机制。一个 socket 描述了通讯连接的一端,两个通讯进程每一个都会有一个 socket ,描述它们之间通讯连接的自己部分。 Socket 可以想象成一种特殊形式的管道,但是和管道不同, socket 对于可以容纳的数据量没有