
1.4 TCP/IP参考模型和TCP/IP
国际标准化组织ISO制订的OSI参考模型提出了网络分层的思想,这种思想对网络的发展具有重要的指导意义。但由于OSI参考模型过于庞大和复杂,所以它难以被投入实际运用中。与OSI参考模型相似的TCP/IP参考模型吸取了网络分层的思想,但是对网络的层次做了简化,并且在网络各层(除主机-网络层外)都提供了完善的协议,这些协议构成了TCP/IP集,简称TCP/IP。TCP/IP是目前最流行的商业化协议,它是当前的工业标准或“事实标准”,TCP/IP主要用于广域网,在一些局域网中也有运用。
TCP/IP参考模型是美国国防部高级研究计划局计算机网(Advanced Research Project Agency Network,ARPANET)以及后来的Internet使用的参考模型。ARPANET是由美国国防部(U.S.Department of Defense,DoD)赞助的研究网络。最初,它只连接了美国境内的四所大学。在随后的几年中,它通过租用的电话线连接了数百所大学和政府部门。最终,ARPANET发展成为全球规模最大的互联网络——Internet。最初的ARPANET则于1990年永久关闭。图1-10把TCP/IP参考模型和OSI参考模型进行了对比。

图1-10 比较TCP/IP参考模型和OSI参考模型
TCP/IP参考模型分为4个层次:应用层、传输层、网络互联层和主机-网络层。每一层都有相应的协议。确切地说,TCP/IP应该被称为TCP/IP集,它是TCP/IP参考模型的除主机-网络层以外的其他三层的协议的集合,而IP和TCP则是协议集的最核心的两个协议。表1-1列出了各层的主要协议,其中主机-网络层的协议是由第三方提供的。
表1-1 TCP/IP参考模型的各层的主要协议

在TCP/IP参考模型中,去掉了OSI参考模型中的会话层和表示层,这两层的功能被合并到应用层,同时将OSI参考模型中的数据链路层和物理层合并到主机-网络层。下面分别介绍各层的主要功能。
(1)主机-网络层
实际上TCP/IP参考模型没有真正提供这一层的实现,也没有提供协议。它只是要求第三方实现的主机-网络层能够为上层——网络互联层提供一个访问接口,使得网络互联层能利用主机-网络层来传递IP数据包。
美国电气及电子工程师学会(Institute of Electrical and Electronics Engineer,IEEE)制定了IEEE802.3和IEEE802.4协议集,它们位于OSI参考模型的物理层和数据链路层,相当于位于TCP/IP参考模型的主机-网络层。采用IEEE802.3协议集的网络被称为以太网,采用IEEE802.4协议集的网被称为令牌环网。以太网和令牌环网都向网络互联层提供了访问接口。
(2)网络互联层
网络互联层是整个参考模型的核心。它的功能是把IP数据包发送到目标主机。为了尽快地发送数据,把原始数据分为多个数据包,然后沿不同的路径同时传递。如图1-11所示,由主机A发出的原始数据被分为3个数据包,然后沿不同的路径到达主机B,可谓殊途同归。数据包到达的先后顺序和发送的先后顺序可能不同,这就需要上层——传输层对数据包重新排序,还原为原始数据。

图1-11 3个数据包沿不同的路径到达主机B
网络互联层具备连接异构网的功能。图1-12展示了其连接以太网和令牌环网的方式。以太网和令牌环网是不同类型的网,两者有不同的网络拓扑结构。以太网和令牌环网都向网络互联层提供了统一的访问接口,访问接口向网络互联层隐藏了下层网络的差异,使得两个网络之间可以顺利传递数据包。

图1-12 网络互联层连接以太网和令牌环网
网络互联层采用的是IP(Internet Protocol),它规定了数据包的格式,并且规定了为数据包寻找路由的流程。
(3)传输层
传输层的功能是使源主机和目标主机上的进程可以进行会话。在传输层定义了两种服务质量不同的协议,即传输控制协议(Transmission Control Protocol,TCP)和用户数据报协议(User Datagram Protocol,UDP)。TCP是一种面向连接的、可靠的协议。它将源主机发出的字节流无差错地发送给互联网上的目标主机。在发送端,TCP负责把从上层传送下来的数据分成报文段并传递给下层。在接收端,TCP负责把收到的报文进行重组后递交给上层。TCP还要处理端到端的流量控制,以避免接收速度缓慢的接收方没有足够的缓冲区来接收大量数据。应用层的许多协议,如HTTP(Hyper Text Transfer Protocol)、FTP(File Transfer Protocol)和TELNET协议等都建立在TCP基础上。
UDP是一个不可靠的、无连接协议,主要适用于不需要对报文进行排序和流量控制的场合。UDP不能保证数据报的接收顺序同发送顺序相同,甚至不能保证它们是否全部到达目标主机。应用层的一些协议,如SNMP和DNS协议就建立在UDP基础上。如果要求可靠的传输数据,则应该避免使用UDP,而要使用TCP。
(4)应用层
TCP/IP模型将OSI参考模型中的会话层和表示层的功能合并到应用层实现。针对各种各样的网络应用,应用层引入了许多协议。基于TCP的应用层协议主要包括以下几类。
·FTP:文件传输协议,允许在网络上传输文件。
·Telnet:虚拟终端协议,允许从主机A登入远程主机B,使得主机A充当远程主机B的虚拟终端。
·HTTP:超文本传输协议,允许在网络上传送超文本,本书第5章(创建非阻塞的HTTP服务器)对此做了进一步介绍。
·HTTPS(Secure Hypertext Transfer Protocol):安全超文本传输协议,允许在网络上安全地传输超文本,网上传输的是经过加密的数据,到达目的地后再对数据解密。
·POP3(Post Office Protocol-Version 3):邮局协议-版本3,允许用户在客户程序中访问在远程服务器上的电子邮件。
·IMAP4(Internet Message Access Protocol Version 4):Internet消息访问协议-版本4,允许用户访问和操纵远程服务器上的邮件和邮件夹。IMAP4改进了POP3的不足,用户可以通过浏览信件头来决定是不是要下载此邮件,还可以在服务器上创建或更改文件夹或邮箱,删除邮件或检索邮件的特定部分。在POP3中,邮件是被保存在服务器上的,当用户阅读邮件时,所有内容都会被立刻下载到用户的机器上。IMAP4服务器可以被看作是一个远程文件服务器,而POP3服务器可以被看作是一个存储转发服务器。
·SMTP(Simple Mail Transfer Protocol):简单邮件传送协议,是发送电子邮件的协议。
基于UDP的应用层协议主要包括:SNMP(Simple Network Management Protocol),即网络管理协议,为管理本地和远程的网络设备提供了一个标准化途径,是分布式环境中的集中化管理协议;DNS(Domain Name System),即域名系统协议,把主机的域名转换为对应的IP地址。
1.4.1 IP
IP网络(即在网络层采用IP的网)中的每台主机都有唯一的IP地址,IP地址用于标识网络中的每个主机。IP地址分为IPv4和IPv6。
(1)IPv4
用32位的二进制序列来表示主机地址。为了便于在上层应用中方便地表示IP地址,可以把32位的二进制序列分为4个单元,每个单元占8位,然后用十进制整数来表示每个单元,这些十进制整数的取值范围是0~255。如某一台主机的IP地址可为192.166.3.4。
相对于IPv6,IPv4是更早期出现的IP地址形式,但现在仍然使用广泛。本书后文在默认情况下采用IPv4地址。
(2)IPv6
用128位的二进制序列来表示主机地址,大大扩充了可用地址的数目,IPv6是新一代的互联网络IP地址标准。
IPv6的128位地址通常分成8段,每段为4个十六进制数。例如:

以上地址比较长,不易于阅读和书写。零压缩法可以用来缩减其长度。如果有一个段或几个连续段的值都是0,那么这些0就可以简单地以“::”来表示。上述地址可写成:

值得注意的是,这种零压缩法只能用一次。例如上例中的“ABAA”后面的“0000”就不能再次简化。这种限制的目的是为了能准确还原被压缩的0,不然就无法确定每个“::”代表多少个0。
另外,如果一个段中包含4个0,那么可以用一个0来表示。以下3个IPv6地址是等价的:

此外,段中前导的0也可以省略,因此以下两个IPv6地址是等价的:

在IPv6地址中可以嵌入IPv4地址,用IPv6和IPv4的混合体来表示。例如:

在以上地址中,“::FFFF”采用IPv6形式,“192.168.89.9”采用IPv4形式。以上地址等价于以下的IPv6地址:

IP地址的组成
下面以IPv4为例,介绍IP地址的组成。IP地址由两部分组成:IP网址和IP主机地址。IP网址表示网络的地址,IP主机地址表示网络中的主机的地址。网络掩码用来确定IP地址中哪部分是网址,哪部分是主机地址。
网络掩码的形式与IP地址相同,但有一定的限制。在网络掩码的二进制序列中,前面部分都为1,后面部分都为0。假定IP地址192.166.3.4的网络掩码为255.255.255.0。这个网络掩码的二进制序列为11111111.11111111.11111111.00000000。把网络掩码与IP地址进行二进制与操作,得到的结果就是IP网址。因此,IP地址192.166.3.4的网址为192.166.3.0。如果把网络掩码设为255.255.0.0,那么IP网址为192.166.0.0。
提示
在Internet上,每个主机都必须有全球范围内唯一的IP地址。国际机构NIC(Internet Network Information Center)统一负责全球地址的规划和管理,与此同时,InterNIC、APNIC、RIPE和CNNIC等机构具体负责美国及全球其他地区的IP地址分配。中国地区的IP地址分配由CNNIC机构负责。
图1-13展示了两个互联的网络的配置,从该图可以看出,每个网络都有IP网址,两个网络之间用路由器连接。

图1-13 每个IP网络都有自己的网址,通过路由器与其他网络连接
子网划分
一个公司可能拥有一个网址和多个主机。例如,如果网址为192.166.0.0,则可以有216(即65536)个主机加入网中。为了更好地管理网络,提高网络性能和安全性,可以把网络划分为多个子网。子网可包括某地理位置内(如某大楼或相同局域网中)的所有主机。例如对于网址为“192.166.0.0”的网络,可从整个网络中分出3个子网,这3个子网的网址分别为:192.166.1.0,192.166.2.0和192.166.3.0,这些子网的掩码都为255.255.255.0。
发送数据包的过程
IP是面向包的协议,即数据被分成若干小数据包,然后分别传输它们。IP网络上的主机只能直接向本地网上的其他主机(也就是具有相同IP网址的主机)发送数据包。主机实际上有两个不同性质的地址:物理地址和IP地址。物理地址是由主机上的网卡来标识的,物理地址才是主机的真实地址。如图1-14所示,主机A向同一个网络上的另一个主机B发包时,会通过地址解析协议(Address Resolution Protocol,ARP)获得对方的物理地址,然后把包发给对方。ARP的运行机制为主机A在网络上广播一个ARP消息:“要寻找地址为192.166.3.5的主机”,接着,具有这个IP地址的主机B就会做出响应,把自身的物理地址告诉主机A。

图1-14 在同一个网络中,主机A直接向主机B发送IP数据包
当主机A向另一个网络上的主机B发送包时,主机A利用ARP找到本地网络上的路由器的物理地址,把包转发给它。路由器会按照如下步骤处理数据包。
(1)如果数据包的生命周期已到,则该数据包被抛弃。
(2)搜索路由表,优先搜索路由表中的主机,如果能找到具有目标IP地址的主机,则将数据包发送给该主机。
(3)如果匹配主机失败,则继续搜索路由表,匹配同子网的路由器,如果找到匹配的路由器,则将数据包转发给该路由器。
(4)如果匹配同子网的路由器失败,则继续搜索路由表,匹配同网络的路由器,如果找到匹配的路由器,则将数据包转发给该路由器。
(5)如果以上匹配操作都失败,就搜索默认路由,如果默认路由存在,则按照默认路由发送数据包,否则丢弃数据包。
从以上路由器的处理步骤可以看出,IP并不保证一定把数据包送达目标主机,在发送过程中,会因为数据包结束生命周期,或者找不到路由而丢弃数据包。
域名
虽然IP地址能够唯一标识网络上的主机,但IP地址是数字型的,用户记忆数字型的IP地址很不方便,于是人们又发明了另一种字符型的地址,即所谓的域名(Domain Name)。域名地址具有易于理解的字面含义,便于记忆。IP地址和域名一一对应。例如JavaThinker网站的域名为www.javathinker.net,对应的IP地址为:43.247.68.17。
域名是从右至左来表述其意义的,最右边的部分为顶层域,最左边的则是这台主机的机器名称。域名一般可表示为:主机机器名.单位名.网络名.顶层域名。如:mail.xyz.edu.cn,这里的mail是xyz学校的一个主机的机器名,xyz代表一个学校的名字,edu代表中国教育科研网,cn代表中国,顶层域一般是网络机构或所在国家地区的名称缩写。
DNS(Domain Name System)协议采用DNS服务器提供把域名转换为IP地址的服务。DNS服务器分布在网络的各个地方,它们存放了域名与IP地址的映射信息。用户需要访问网络上某个主机时,只需提供主机直观的域名,DNS协议首先请求地理位置比较近的DNS服务器进行域名到IP地址的转换,如果在该服务器中不存在此域名信息,那么DNS协议再让远方的DNS服务器提供服务。
URL(统一资源定位器)
URL(Uniform Resource Locator),即统一资源定位器。它是专为标识网络上资源位置而设的一种编址方式,大家熟悉的网页地址就属于URL。URL一般由3部分组成:
应用层协议://主机IP地址或域名/资源所在路径/文件名
例如JavaThinker网站提供的JDK安装软件包的URL为:

其中“http”指超文本传输协议,“www.javathinker.net”是Web服务器的域名,“software”是文件所在路径,“jdk8.exe”才是相应的文件。
在URL中,常见的应用层协议还包括ftp和file等,比如:

以上file协议用于访问本地计算机上的文件,使用这种协议的URL以“file:///”开头。
1.4.2 TCP以及端口
IP在发送数据包的途中会遇到各种状况,例如可能路由器突然崩溃,使数据包丢失。再例如可能前面的数据包沿低速链路移动,而后面的数据包沿高速链路移动而超过前面的包,最后使得数据包的顺序混乱。
TCP使两台主机上的进程顺利通信,不必担心数据包丢失或顺序混乱。TCP跟踪数据包顺序,并且在数据包顺序混乱时按正确顺序对其进行重组。如果数据包丢失,则TCP会请求源主机重新发送。
如图1-15所示,两台主机上都会运行许多进程。当主机A上的进程A1向主机B上的进程B1发送数据时,IP根据主机B的IP地址,把进程A1发送的数据送达主机B。接下来,TCP需要决定把数据发送到主机B中的哪个进程。TCP采用端口来区分进程。端口不是物理设备,而是用于标识进程的逻辑地址,更确切地说,是用于标识TCP连接端点的逻辑地址。当两个进程进行一次通信时,就意味着建立了一个TCP连接,TCP连接的两个端点用端口来标识。在图1-15中,进程A1与进程B1之间建立了一个TCP连接,进程B1的端口为80,因此进程B1的地址为主机B:80。进程A1的端口为1000,因此进程A1的地址为主机A:1000。每个进程都有了唯一的地址,TCP就能保证把数据顺利送达特定的进程。

图1-15 TCP采用端口来区分进程间的通信
提示
在客户/服务器模型中,客户进程可能会与服务器进程同时建立多个TCP连接,在客户端,每一个TCP连接都被分配一个端口。参见1.5.2节的图1-21。

图1-21 客户与服务器进程之间同时建立了两个连接
端口号的范围为0到65535,其中0到1023的端口号一般被固定分配给一些服务。比如21端口被分配给FTP服务,25端口被分配给SMTP(简单邮件传输)服务,80端口被分配给HTTP(超级文本传输)服务,135端口被分配给RPC(远程过程调用)服务等等。
从1024到65535的端口号供用户自定义的服务使用。比如假定本章范例中的EchoServer服务使用8000端口。当EchoServer程序运行时,就会占用8000端口,当程序运行结束时,就会释放所占用的端口。
客户进程的端口一般由所在主机的操作系统动态分配,当客户进程要求与一个服务器进程进行TCP连接时,操作系统会为客户进程随机地分配一个还未被占用的端口,当客户进程与服务器进程断开连接时,这个端口就被释放。
此外还要指出的是,TCP和UDP都用端口来标识进程。在一个主机中,TCP端口与UDP端口的取值范围是各自独立的,允许存在取值相同的TCP端口与UDP端口。如图1-16所示,在主机A中,进程A1占用FTP端口1000,进程A2占用UDP端口1000,这是被允许的。

图1-16 TCP端口与UDP端口的取值范围各自独立
1.4.3 RFC简介
TCP/IP是以RFC(Request For Comment)文档的形式发布的。RFC指描述互联网相关技术规范的文档。
RFC由个人编写,这些人自愿编写某一新协议或规范的提议草案,并提交给Internet工程任务组织(The Internet Engineering Task Force,IETF)。IETF负责审阅和发布这些被统称为RFC的文档,每个文档都有一个RFC编号,并且处于以下六种类型之一。
·标准协议:Internet 的官方标准协议。
·标准协议草案:正在被积极地考虑和审阅以便成为标准协议。
·标准协议提议:将来可能变成标准协议。
·实验性协议:为实验目的而设计的协议。实验性协议不投入实际运用。
·报告性协议:由其他标准组织开发的协议。
·历史性协议:已经过时的协议,被其他协议代替。
在FRC的官方网站上已经发布了8000多份RFC文档。表1-2列出了与TCP/IP 协议相关的RFC文档编号。
表1-2 与TCP/IP 协议相关的 RFC文档编号

在FRC的官方网站上输入网址:http://www.ietf.org/rfc/rfcXXXX.txt,就能查看相关的FRC文档,这里的XXXX表示文档编号。
RFC文档一旦被正式发布,其编号和内容就不允许改变。如果需要更新RFC文档,则会对更新后的RFC文档赋予新的编号,再将它发布。例如HTTP1.0协议对应的RFC文档编号为RFC1945,它的升级版本HTTP1.1协议对应的RFC文档编号为RFC2068。
1.4.4 客户/服务器通信模式
TCP/UDP推动了客户/服务器通信模式的广泛运用。在通信的两个进程中,一个进程为客户进程,另一个进程为服务器进程。客户进程向服务器进程发出要求某种服务的请求,服务器进程响应该请求。如图1-17所示,通常,一个服务器进程会同时为多个客户进程服务,图中服务器进程B1同时为客户进程A1、A2和B2提供服务。以下伪代码演示了服务器进程的大致工作流程:


图1-17 客户进程A1、A2和B2请求服务器进程B1的服务
服务器进程可以提供各种各样的服务,例如1.1节提到的EchoServer提供的服务为根据EchoClient发出的字符串XXX,返回字符串“echo:XXX”。除了像EchoServer这样的由用户自定义的服务,网络上还有许多众所周知的通用服务,最典型的是HTTP服务。网络应用层的协议规定了客户程序与这些通用服务器程序的通信细节,例如HTTP规定了HTTP客户程序发出的请求的格式,还规定了HTTP服务器程序发回的响应的格式。
在现实生活中,有些重要的服务机构的电话是固定的,这有助于人们方便地记住电话和获得服务,比如众所周知的电话110、120和119分别是报警、急救和火警电话。同样,在网络上有些通用的服务有着固定的端口,表1-3对常见的服务以及相应的协议和端口做了介绍。
表1-3 应用层的一些通用服务使用的端口
