网络概念HOWTO

译自Networking Concepts HOWTO,原文作者Rusty Russell。

目录

1 介绍

欢迎,亲爱的读者

过去我写过不少关于网络的HOWTO,但后来我觉得,它们都是一堆术语堆砌起来的地狱。我有三个选择:另外两个选择是,过在所有出现的地方解释这些术语,以便解决这个问题。但这些都没有吸引力。

自由软件的关键,是你应该对使用的软件系统拥有探索和玩耍的自由。我相信,让人们感受到这样的自由是一个高贵的目标。之所以这么说,不只是因为在追寻的过程中人们感觉到自主权(就像重建一个汽车引擎那样),还因为当今的互联网和自由软件都允许你把经验分享给数百万的人。

但你必须从某个地方开始,就从这里开始吧。

2 什么是“计算机网络”?

计算机网络只是一套让节点(node)间互相通话的东西(我说的“节点”是指电脑、打印机、可乐机,还有任何你能想到的东西)。不管它们怎样连接,这真的不重要:可以用光纤或者信鸽。显然,一些选择会比其他选择更好(特别是当你养了一只猫的时候)。

如果只是把两台电脑连接起来,通常不把这叫做网络;你需要3台或者更多来组成一个网络。这有点像“组(group)”这个字:两个人只是一对家伙(a couple of guys),但是3个人就是一个“组”了。而且,为了组建更大的网络,常常把网络“勾(hook)”在一起;每个小的网络(通常称为“子网”)都可以是大的网络的一部分。

两台电脑间实际的连接通常叫做“网络连接(network link)”。如果你电脑后面的几条线缆连到了其他机器上,这就是你的网络连接。

谈到计算机网络,我们常常在意四件事:

大小

如果只是把家里面的4台电脑连接起来,你就有了一个LAN(Local Area Network,局域网)。不管连接了多少电脑,不管有什么建造了这个网络,如果所有的东西都在步行范围内,通常就称为LAN。

光谱的另一头是WAN(Wide Area Network,广域网)。如果你的一台电脑在巴基斯坦的拉合尔,另一台在英国伯明翰,还有一台在智利的圣地亚哥,并且你还能连接到它们,那这就是一个WAN。

拓补:形状

画一幅互联网的示意图:连接线是网络连接,节点是一个点。或许所有的线连接到一个中心点,就像一一颗大的星星,也就是所有“人”通过一个点对话(一个“星形拓补”):

    o   o   o
     \_ | _/
       \|/
  o-----o-----o
      _/|\_
     /  |  \
    o   o   o

或许所有“人”在一条线上对话,像这样:

    o------o------o-------o--------o
    |                              |
    |                              |
    |                              o
    |                              |
    o                              |
                                   o

或许你有3个子网,它们通过一个节点连接在一起:

                o
    o           |  o--o--o
    |           |  |
    o--o--o--o--o  o
           \       |
            o------o
           /       |
    o--o--o--o--o  o
    |           |  |
    o           |  o--o
                o

在现实生活中能够见到很多类似这些的例子,还有很多更加复杂的。

物理:它是用什么做的

我们要关心的第二件事是,用什么组建网络。最便宜的是“跑腿网络(sneakernet)”,穿着差劲的人们把软盘从一台机器扛到其他机器。跑腿网络几乎都是LAN。软盘只需要1美元,一双结实的运动鞋大概需要20美元。

最常见的,连接家庭电脑和外部巨型网络的系统被称作“猫(调制解调器)”。猫把普通的电话连接转换成网络连接。它把电脑发出的那些东西转化成声音,同时接听电话线另一头的声音并转化成电脑能用的东西。你可以想到,由于电话线并不是为这个用途设计的,这并不怎么高效,但电话线很普遍,所以这很便宜:猫的售价少于50美元,电话线通常一年的开销是几百美元。

把机器连接到LAN最常见的方式是使用以太网(Ethernet)。以太网有这些主要的类型(按从旧到新顺序列出):细导线(Thinwire)/同轴电缆(Coax)/10base2,UTP (Unshielded Twisted Pair,未屏蔽双绞线)/10baseT and UTP/100baseT。G级以太网(gigabit ethernet,“1000baseT”这个名字开始变得有点傻了)也已经开始部署。10base2线缆通常是同轴电缆,把T形头拧在上面连接到其他的东西上:所有人连接到一条大线上,线的两头是特殊的“终结器(terminator)”。UTP通常是蓝色线缆,有着像电话线那样清晰可辨的“压入式”连接头,插到专用插槽上进行连接:每条线连着一个节点和一个中心“集线器(hub)”。线缆几美元一米,10baseT/10base2卡(许多卡同时拥有这两种插槽)已经很难找到全新的了。100baseT卡兼容10baseT,同时比它快10倍,大概30美元。

上述一系列“光谱”的另一端是光纤:一条很细的连续玻璃长丝,被保护性外皮包裹,可用来在大陆间传递信息。一般来说,光纤需要花费数千美元。

我们通常把到每个节点的连接称作“网络接口(network interface)”,或简称“接口(interface)”。在Linux中,第一个以太网接口的名字一般是“eth0”,第一个光纤接口的名字一般是“fddi0”。“/sbin/ifconfig”命令可以把它们列出来。

协议:他们说什么

最后一件需要关心的事是两个节点间说什么语言。当两个猫通过电话线交谈的时候,他们需要在某个声音代表什么含义这件事情上达成一致,否则是无法工作的。这个约定被称作“协议(protocol)”。当人们发现了新的方式,可以把计算机说的话编码成更小的声音的时候,新的协议就发明出来了;至少有一打不同的调制解调器协议,大部分的猫都会尝试多种不同的协议,直到可同其他猫交流。

另外一个例子是上面提到的100baseT网络:它使用和10baseT相同的网络连接(UTP),但比它说话速度快10倍。

这两个协议都是“链路级(link-level)”协议;描述怎样在独立的网络连接,或“一跳(one hop)”,间传递东西。“协议”这个词同样也适用于紧随链路级的一些约定,我们下面就会看到。

3 什么是“互联网”?

互联网是一个遍布全球的WAN:它是现存的最大的计算机网络。“网间互通(internetworking)”这个词指的是用互相分离的网络建造一个更大的,因此“互联网”是一大堆子网间的连接。

现在我们看看上面列出的那些内容,然后提出疑问:Internet有多大,它的物理细节和协议都是什么?

大小其实上面已经说了:全球。

然而物理细节是变化的:每个小子网的连接都存在不同之处,有着不同的布局和物理性质。想绘出可用的互联网图像的尝试最终都会失败。

每个连接所使用的协议通常也是不同的:所有上面列出的链路级协议都在使用,还有更多其他的。

3.1 互联网怎么工作?

问题又来了:既然节点都是用不同的链路级协议进行对话的,那么互联网上每个节点间是如何互相通信的呢?

答案很简单:我们需要另一个协议,用来控制数据如何在网络间流动。链路级协议描述如何从直接连接在一起的一个节点到达下一个节点:“网络协议(network protocol)”告诉我们怎样从网络上的一个点到达另一个点,如果必要,可以穿过其他链路。

互联网上的网络协议,是互联网协议(Internet Protocol,第4版),或简称IP。它不是唯一的协议(Apple的AppleTalk,Novell的IPX,Digital的DECNet和Microsoft的NetBEUI是其他协议),但是最广泛接受的协议。还有一个IP协议的新版本称作IPv6,但还不普遍。

因此为了从地球的一边向另一边发信息,你的电脑会写一些IP协议,把它发给你的猫。然后你的猫使用一些调制解调器链路级协议把信息发送给它拨号连接的另一个猫。这个猫可能被插在一个终端服务器上(基本就是一个装满猫的大盒子),然后终端服务器把信息发送到ISP网络的一个节点,这个节点再把信息发送到(通常是)一个更大的节点,这个更大的节点再把信息发送到下一个节点……如此往复。连接两个或多个网络的节点叫做“路由器”:每一个网络在它上面都有一个对应的接口。

我们把这一系列协议称为“协议栈(protocol stack)”,画出来通常是下面的样子:

   [ 应用程序: 处理色情作品 ]                     [ 应用层:伺服色情作品 ]
              |                                          ^
              v                                          |
    [ TCP: 处理数据包转发 ]                      [ TCP: 处理数据包转发 ]
              |                                          ^
              v                                          |
     [ IP: 处理数据包寻路 ]                       [ IP: 处理数据包寻路 ]
              |                                          ^
              v                                          |
   [ 链路层: 处理单独的一跳 ]                   [ 链路层: 处理单独的一跳 ]
              |                                          |
              +------------------------------------------+

在这个表格中,我们看到Netscape(左上的应用程序。一个已经死掉很久的浏览器——译者注。)从网站服务器(右上的应用层)获取一个网页。为了做到这一点它会用到“传输控制协议(Transmission Control Protocol)”或简称“TCP”:由于网页和电子邮件传输都用到它,现在90%的互联网流量都是通过TCP在传输。

Netscape向远端服务器发起一个TCP连接请求:请求被发到TCP层,TCP把它交给IP层,IP层找出传输路径,把它交给链路层,然后链路层把这个请求传输到连接的另一端。

在另一端,链路层把它传递给IP层,IP层看到他的目的地是当前主机(如果不是,IP层可能会把它传递给其他链路层,以便发往下一个节点),把它传递给TCP层,TCP层再把它传递给服务器。

因此,我们可以详细列出如下:

  1. 应用程序(Netscape,或者另一端的网站服务器)决定它要和谁通话,它想发送什么内容。
  2. TCP层发送特殊的数据包,以便与另一端开始通话,然后把数据打包进TCP“数据包(packet)”里:数据包是在网络上传输的一段数据段。TCP层把这个数据包传给IP层:它被持续发往IP层,直到另一端回复说已收到。这被称为“重发(retransmission)”,有一整堆的复杂规则控制什么时候重发,等待多长时间,等等。TCP层会给每个数据包指定一个编号,以便另一端可以按正确的顺序组装成完整的数据。
  3. IP层寻找数据包的目的地,决定接下来发往哪一个节点。这一简单的行为被称作“寻路(routing)”。寻路可以极简单(如果你只有一个猫,没有其他网络接口,所有数据包都会发往那个接口),也可以极复杂(如果有15个重要的网络直接和你连接)。

4 关于IP

所以IP层的角色是如何找出把数据包发到他们的最终目标的路径。为了让这一点成为可能,网络上的每个接口需要一个“IP地址(IP address)”。IP地址由4个数字组成,他们之间被英文句号(.)隔开,例如“167.216.245.249”。每个数字的范围在0~255之间。

同属一个网络的接口一般会有相近的IP地址。比如“167.216.245.250”这台机器就在“167.216.245.249”的旁边。同时需要了解路由器是一个在多个网络都有接口的节点,因此每个接口都会有一个IP地址。

因此Linux内核的IP层会维护一个路由表,表中描述了怎么到达某个IP地址组。最简单的路由表当属“默认路由(default route)”:如果IP层不知道向哪里发送数据包,则会发送至默认路由。使用“/sbin/route”可以看到一个路由的列表。

路由可以指向一个连接,也可以是一个连接到其他网络的特殊节点。例如,当你拨号到ISP时你的默认路由会指向猫的连接,因为整个世界都在那儿。

  Rusty的              ISP的  ~~~~~~~~~~~~ 
    猫                  猫   {             }
       o------------------o {    互联网     }
                             {            }
                              ~~~~~~~~~~~~

但如果在你通往外部世界的网络上连着其他机器,情况会变得有点复杂。在下面的表格里,我的机器能直接和Tridge、Paul的机器,还有防火墙通话,但它需要知道前往世界其他地方的数据包应发往防火墙,只有防火墙才能把它们传递出去。这意味着你有两条路由:一条记录着“如果它在我的网络里,那么直接发到那”,还有一条默认路由“如果不在我的网络,把它发给防火墙”。

                         o  Tridge的
                         |    工作电脑           ~~~~~~~~~~~~
      Rusty的            |                     {            } 
        工作电脑 o--------+-----------------o--{    互联网     }
                         |              防火墙  {            } 
                         |                      ~~~~~~~~~~~~
                         o  Paul's
                              工作电脑

4.1 IP地址组:网络掩码

还有最后一个细节:对IP地址组,有标准的记法,有时会被称为“网络地址(network address)”。就像电话号码能被分为“地区前缀+其他”一样,我们也能把IP地址分为“网络前缀+其他”。

人们习惯于谈到“1.2.3网络”,意思是从1.2.3.0到1.2.3.255的所有256个IP地址。如果这不是一个足够大的网络,他们或许会谈到“1.2网络”,其地址范围是1.2.0.0到1.2.255.255。

我们通常不写“1.2.0.0-1.2.255.255”,而是把它简写为“1.2.0.0/16”。这个奇怪的“/16”记法(它被叫做“网络掩码(netmask)”)需要一点小小的解释。

IP地址里每两个点之间的数字实际上是一个8位的二进制数字(从00000000到11111111):我们用十进制写这些数字是为了让人们更好认。“/16”的意思是前16位二进制数字是网络地址,也就是,“1.2”这部分是网络(要记得:每个数字代表8位二进制数)。意思是任何以“1.2”打头的IP地址都是网络的一部分:“1.2.3.4”和“1.2.3.50”是,“1.3.1.1”不是。

为了让生活容易一些,我们通常使用“/8”、“/16”、“/24”结尾的网络。例如“10.0.0.0/8”是一个包含10.0.0.0到10.255.255.255(超过1600万地址!)的大网络。10.0.0.0/16要小一些,只包含从10.0.0.0到10.0.255.255的IP。10.0.0.0/24更小,包含的地址从10.0.0.0到10.0.0.255。

为了让人们更加疑惑,还有另一个表示网络掩码的方式。可以把掩码写的像IP地址那样:

10.0.0.0/255.0.0.0

最后,所有网络里面的最高位IP都是没有价值的,它被保留做“广播地址(broadcast address)”,我们可以用这个地址一次性给网络里所有人发消息。

下面是网络掩码的一个表格:

短形式   完整形式                 最大机器数        备注

/8      /255.0.0.0              16,777,215      习惯上被称为“A类”
/16     /255.255.0.0            65,535          习惯上被称为“B类”
/17     /255.255.128.0          32,767
/18     /255.255.192.0          16,383
/19     /255.255.224.0          8,191
/20     /255.255.240.0          4,095
/21     /255.255.248.0          2,047
/22     /255.255.252.0          1,023
/23     /255.255.254.0          511
/24     /255.255.255.0          255             习惯上被称为“C类”
/25     /255.255.255.128        127
/26     /255.255.255.192        63
/27     /255.255.255.224        31
/28     /255.255.255.240        15
/29     /255.255.255.248        7
/30     /255.255.255.252        3

5 机器名和IP地址

所以每一个节点的每一个接口都有一个IP地址。人们很快意识到记忆数字是很糟糕的事情,因此(就像电话号码那样)我们需要一个名称簿。不过既然我们在用电脑,让电脑自己给我们找名字是再合适不过了。

因此,我们有了域名系统(DNS)。有一些大家都知道其IP地址的节点,程序可以到这些节点查找名称,并收到与之相应的IP地址。几乎你将使用的所有程序都能做到这一点,这就是为什么只需要在浏览器输入“www.linuxcare.com”就可以,而不是“167.216.245.249”。

当然,你需要知道至少一台“域名服务器(name server)”的IP地址:通常它们被保存在“/etc/resolv.conf”文件中。

既然DNS查询信息及其返回信息都相当小(都只有1数据包),通常不会使用TCP协议:虽然他提供诸如自动重传,排序等特性,通常很可靠,但实现这些的代价是在网络上法索额外的数据包。代之以非常简单的“用户数据报协议(User Datagram Protocol)”,它不提供我们不需要的所有TCP梦幻特性。

6 不同的服务:电子邮件,网页,FTP,域名服务

早先的例子中,我们演示了Netscape向另一个节点上运行的网页服务器发送TCP请求。不过我们可以想象一下,那个运行王爷服务器的节点同时还是一个电子邮件服务器、一个FTP服务器和一个域名服务器:它怎么知道TCP连接是给哪个服务器用的?

这就引出了TCP和UDP的“端口(port)”概念。每个数据包都有一个存放“目的端口(destination port)”的空间,它指出了用到这个数据包的服务。例如邮件服务器使用TCP端口25,网页服务器使用TCP端口80(虽然有时你会发现网页服务器运行在不同的端口上)。“/etc/services”文件里有一份端口列表。

还有,如果两个Netscape窗口同时在访问同一个网站的不同部分,运行Netscape的Linux主机是如何知道服务器返回的TCP数据包是给哪个窗口用的?

这又引出了“源端口(source port)”的概念:每个新的TCP连接都有一个不同的源端口,所以即使它们的目标IP地址和目标端口是相同的,照样可以把它们区分开。通常分配的第一个源端口是1024,随着时间的增长端口号会递增。

7 拨号接口:PPP

当你用猫拨号到ISP,连接到他们的猫的时候,内核不是随便就这样让IP通过它了。有一个“点对点协议(Point-to-Point Protocol)”,或简称“PPP”,在发送数据包之前,和另一端进行协商。ISP用它辨别是谁在拨号:在你的Linux主机商,一个叫做“PPP 守护程序(PPP daemon)”的东西在处理你这一端的协商。

由于时间上有非常多的拨号用户,他们通常不具有自己的IP地址。大部分ISP会在你拨号时临时分配一个他们的IP地址给你(PPP守护程序会协商这些事物)。这通常被称为“动态IP地址(dynamic IP address)”,与“静态IP地址(static IP address)”的区别是通常你自己的IP地址是永久的。动态IP地址由猫分配:下次你拨号的时候很可能会连接到ISP那一堆猫中的另外一个猫上,因此就有了不同的IP。

8 数据包是什么样的

由于异常好奇(且好奇异常),这里我们描述一下数据包实际看起来是什么样子。有不少工具可以观察进出你Linux主机主机的数据包:最常用的是“tcpdump”(现在它懂得的已经不止TCP了),但一个更好的是“ethereal”。这些程序叫做“数据包嗅探器(packet sniffer)”。

每个数据包的开始部分会说出它要到哪里,它从哪里来的,数据包的类型还有其他一些管理细节。这个部分叫做“数据包头(packet header)”。数据包剩下的部分,包含着实际传输的数据,通常叫做“数据包身(packet body)”。

所以任何一个IP数据包以“IP头”开始:至少20字节长。它看起来像(这个表格是厚着脸皮从RFC791偷过来的):

  .-------+-------+---------------+-------------------------------.
  |  版本  |  IHL  |   服务类型     |             总长度             |
  |-------+-------+---------------+-------------------------------|
  |             识别码             | 标记 |        片段偏移          |
  |---------------+---------------+-------------------------------|
  |    存活时间    |      协议      |            头部校验和          |
  |---------------+---------------+-------------------------------|
  |                             源地址                             |
  |---------------------------------------------------------------|
  |                            目标地址                            |
  `---------------------------------------------------------------'

最重要的部分有协议——他指出这是一个TCP包(数字6)、一个UDP包(数字17)还是其他什么东西,源IP地址及目的IP地址。

现在,如果协议部分说这是一个TCP包,那么紧跟着IP头的会是一个TCP头:TCP头也是至少20字节长:

  .-------------------------------+-------------------------------.
  |             源端口             |             目标端口           |
  |-------------------------------+-------------------------------|
  |                             顺序号                             |
  |---------------------------------------------------------------|
  |                             确认号                             |
  |-------------------+-+-+-+-+-+-+-------------------------------|
  |  数据  |           |U|A|P|R|S|F|                               |
  |  偏移  |   保留区   |R|C|S|S|Y|I|               窗口            |
  |       |           |G|K|H|T|N|N|                               |
  |-------+-----------+-+-+-+-+-+-+-------------------------------|
  |             校验和             |             紧急指针           |
  `---------------------------------------------------------------'

这里最重要的区域是源端口,目的端口,他们表明数据包要去到哪一个服务(对应答数据包来说,从哪一个服务发出)。顺序号和确认号用来保障数据包的顺序,并告诉另一端它已收到了哪些数据包。ACK、SYN、RST还有FIN这些标记(上图中从上往下写的那些字母)是单独的二进制位,用来协商打开(SYN)和关闭(RST或FIN)连接。

跟在这个包头后面的是应用程序发送的实际数据(数据包身)。一般数据包大小是1500字节:这意味着数据最大会占用1460字节(IP头用掉20字节,TCP头用掉20字节):超过了97%。

9 摘要

所以现代的互联网使用IP包通信,大多数这些IP包里面运输的是TCP包。叫做“路由”的特殊节点把所有小的网络连在一起组成大的网络,同时让这些数据包穿过网络到达目的地。大多数机器只连接到一个网络上(也就是说,只有一个接口),路由器除外。

每个接口有一个唯一的IP地址,看起来像“1.2.3.4”这样:同一个网络的接口有着相关联的IP地址,这些IP有着相同的开头,就像同一地区的电话号码前面部分都相同。网络地址看起来像IP地址,但它有一个“/”后缀,说明其中的多少位是网络前缀。例如“1.2.0.0/16”亦为之前两位数字是网络地址:每个数字代表8个比特。

域名系统赋予机器以名称:程序问域名服务器一个类似“www.linuxcare.com”的域名,服务器会回答这个域名对应的IP。这个IP地址会被用作目标IP地址,以便与那个节点进行通信。

Rusty真的不擅长写文档,特别是给初学者写文档。

祝你愉快!

Rusty。

10 致谢

感谢Alison,坐在那里把我那糟糕的草稿看了一遍,并且用可能是最好的方式,告诉我我写的烂透了。

11 译者后记

虽然原文写于十多年前的2001年,但今天读来依然很有价值,其中的内容大部分也并未过时,不失为一篇很好的网络入门教材。

本人出于温习并让自己记忆深刻的目的,翻译了整篇文章。翻译经验有限,只求译文在尽量接近文章原义的基础上保持通顺。其中的有些术语翻译比较随意,或许会与通常叫法有所不同。

点击量:63

发表评论

电子邮件地址不会被公开。 必填项已用*标注

17 − 7 =