前言
在第一章中我们大致的了解了互联网的全貌,我们简略的提及了两个主机间通信的过程,让我们再来回顾一下这个过程,一台主机向另外一台主机发送信息,信息先经历自身主机的五层封装,然后通过物理层的链路向路由器或者电路转换器发送向目标主机,再经历目标主机的五层拆解,最终用户得到了你想要发送的信息。这其中最关键的自然是网络的五个层级,自顶向下分别为应用层、传输层、网络层、链路层、物理层。接第一章中我们大致的了解了整个网络世界的框架,接下来我们需要更加深入的了解每个层级,根据自顶向下的原理,自然而然的我们需要介绍应用层。
在开始之前我们先问自己一个问题。我们为什么需要网络?
回答这个问题的方式十分简单,想象一下如果我们没有了网络我们将会怎么样,断网的一天,你待在家里,没法和别人打游戏、发消息、上网浏览信息… 正是我们需要这些服务,我们才需要网络来帮助我们来实现。这些服务也称之为网络应用。有趣的网络应用是因特网成功的驱动力,而这些应用处于的层级我们很自然的称之为应用层。
2.1 应用层协议原理
让我们来考虑一下假设你有一个极佳的想法,比方说你想要创造一个网络应用能够让用户互相分享自身喜欢的音乐的应用。那么该如何实现呢?你或许需要借助一种编程语言例如:C、C++、JAVA、Python 来编写这个应用程序,同时你需要考虑到,这个应用可能需要在不同的系统上来进行运行这可让人头大,但是幸运的是,我们不需要写在网络核心设备如路由器或者链路层交换机上运行的软件,这种设计方式即将应用程序限制在端系统的方法,在第一章中我们知道了分层的概念,在应用层之下是传输层,这也意味着你无需理会网络层、链路层的相关细节。需要考虑网络层的是传输层,以此类推,也就是你想要写一个应用只需要借助传输层的一些功能来帮助你来完成你所需要的所有要求。
2.1.1 网络应用程序体系的结构
网络程序的体系结构明显不同于网络的体系结构,网络的体系结构是确定的五个层级,而程序的结构设计则随着程序员的想法而变动,这里介绍两个主流的框架
- 客户——服务器体系结构
- 对等(P2P)
客户——服务器结构
在这个架构中,总有一个开着的服务器来响应客户端,例如最出名的搜索引擎——谷歌,采用的就是这个模式,在这个模式下,两个浏览器间并不直接通信,而是借助服务器来传输信息,这种大型服务器也被称之为数据中心,因为它必须能够满足大量的用户需求,这也意味着的需要更多的资金,这种模式的优势体现在只要服务器足够强大,马上数据的传输将会更加的安全。
P2P
这个模式与上一种模式最大的区别就是无需借助服务器的帮助。应用程序在间断连接的主机之间直接通信,这些主机被称为对等方。同时P2P最引人入胜的地方是其自拓展性,例如在一个P2P文件共享应用中,尽管每个对等方都由于请求文件产生工作负载,但每个对等方通过向其他对等方分发文件来为系统增加服务能力。这种模式无需服务器,所有更具有经济效益。然而在高度非集中式结构,面临着安全性,性能和可靠性等挑战。
2.1.2进程通信
在构建网络应用程序前,我们还需要对运行在多个端系统上的程序事如何通信的情况有一个基本的了解。用操作系统的术语来说,进行通信实际上是一个进程(process),那么什么是进程呢,简单来说就是正在运行的程序。在同一台主机上运行的不同进程通过进程间的通信机制来相互通信。进程间的相互通信规则则由操作系统来确定。而不同的主机间进行进程的通信的方式则是跨越计算机网络来交换报文来互相通信,下面我们来分析一下两个主机之间的进程通信。
-
客户和服务器的进程
网络应用的进程一定是成对出现的,这比较好理解,毕竟你需要与别人通信,那么这两台主机有什么区别呢?通常我们将发起通信的进程标识为客户。在会话开始时等待联系的主机称之为服务器。 -
我们知道应用层通过运输层来完成报文的交换,那具体的过程是怎么样的呢。通常传输层会给应用层提供一个软件接口我们又称之为套接字(socket),客户端的报文放入主机的套接字软件,随后服务器的套接字软件来接受客户端的报文。套接字是建立于网络应用的可编程接口,因此又称为应用程序编程接口(Application Programming Interface API),程序员可以控制套接字在应用端的一切,但是在传输层几乎没有操作空间。所以对于一般的网络编程而言,套接字是工作中最常见的编程作业。
-
进程寻址
通信的过程类似与发送邮件,我们必须将自身主机的地址与目的主机中指定接受进程的标识符在报文中写清楚,通信才能被正确的连接。在因特网中,主机由IP地址来标识,简单来说IP地址就是一个32比特的量且它能够唯一的标识该主机,就像每个人的身份证一样。而标识符也叫做端口号,由于服务器需要接受多个客户端的请求,但是每个客户端请求的内容可能不同,所以再细致的分为不同的端口号,常见的Web服务器用端口号80来标识。而邮件服务器用端口号25来标识,这些都是约定熟成的。
2.1.3 可供应用程序使用的运输服务
上面我们提到了套接字这个概念,在发送端的应用程序将报文推进套接字,在该套接字的另外一侧,运输层协议负责从接受进程的套接字得到该报文。
但是包括因特网在内的很多网络提供了不止一种的运输层协议。当开发一个应用时必须选择一种可用的运输车协议。该如何做出这种选择,是我们需要思考的一个很重要的问题。通常我们需要考虑运输层协议提供的服务,选择一个最为适合的一个,在服务中每个协议都有其擅长的一部分。我们大体能够从四个方面对应用服务程序进行分类:可靠的数据传输、吞吐量、定时、安全性,下面我们来简略的来解释这四个概念。
-
可靠的数据传输
在第一章中我们知道,分组在计算机网络中由于各种因素可能被丢失,一般像发送邮件这种需求,数据的丢失是难以被接受的,因此为了支持这些应用必须做一下工作来确保由应用程序的一段到另外一端发送的数据正确,如三次握手、四次挥手。有些数据的丢失是可以被允许的,如音频文件。所以我们常常看见音乐的下载有无损音质、普通音质这些差别,由于人的耳朵并没有那么敏感,丢失数据可能会出现一些小干扰,但不是致命的。 -
吞吐量
在第一章中我们提及过这个概念,吞吐量(网速)就像是一种资源,我们当然希望吞吐量越大越好,这意味着数据传输的速度更快,但是由于资金等方面的因素,我们需要合理的利用这个资源,类似即时通话这类型的应用对于吞吐量的要求就相对较高。 -
定时
定时的概念与吞吐量类似,大致意思就是保证数据传输在一定的时间范围内传输完成。 -
安全性
这个概念从字面上就可以理解,可靠的数据传输保证数据的不丢失,而安全性保证了数据的私密性。没有安全性的保证,数据将会被随意的窃取,这对于一些机密而言是不可忍受的,但是对于一些随处可见的资料来说,安全性就没有那么总要。
以上我们了解了不同的应用,需要应用不同的服务。我们当然希望数据的传输更加可靠、更加快速、更加安全。但是情况往往不允许我们鱼和熊掌兼得,适当的做出取舍是程序员的必备素养。
2.1.4 因特网提供的运输服务
在应用层中,主流的协议有两种TCP、UDP,作为开发者,往往我们的选择是二者中的其中一个。下面我们来讨论一下二者区别。
- TCP服务
TCP服务模型中包括了面向连接服务和可靠数据传输服务,面向连接的服务,在握手阶段完成,在前面的内容中我们简略的解释了三次握手,一个TCP连接是双向的,双方的进程可以同时进行报文的发送,而结束发送报文时需要断开连接。至于可靠的数据传输服务,可参照上面的解释来理解。总而言之TCP通过连接提供了更可靠的数据传输。 - UDP服务
UDP相较于TCP,它仅提供最小的服务且是无连接的。这样做的好处是,它的过程更加简单迅速。相对的UDP协议并不保证该报文将到达接受进程,而且到达接受进程的报文也可能是乱序的。
因特网服务中不提供的服务
上面两种协议我们主要讨论了数据的可靠传输这方面的需求差异。然而并未提及其他三个方面的内容,这是因为在多年的网络服务中,吞吐量以及定时这两种协议完成的都十分不错。这也是用户更加直观体验到的方面,无论那种服务,我们都希望得到更加快速的响应。至于安全性,TCP在应用层提供了SSL来加强安全性,在TCP和UDP中二者都未对数据加密进行处理,而SSL可以看作加强版的TCP,它在应用层帮助TCP完成更好的安全性。
2.1.5 应用层协议
我们刚学习了通过报文发送进套接字并实现网络进程间的互相通信。但是如何构造这些报文?这些报文的各个字段的含义是什么?进程何时发送这些报文?这些问题的回答需要我们更加深入的了解应用层协议的具体内容。在应用层协议中详细的定义了这些问题的答复,具体的内容放在后面来讲。
2.1.6 本书涉及的网络应用
如今有大量的网络应用被提出,而在本书中将会挑选其中几个来讲解。如Web、文件传输、电子邮件、目录服务、流式视频、和P2P,这些同样会在后文中,提供给大家学习。
总结
在这小节中我们学习了进程间的通信与应用层的结构,以及相应概念,知道了不同的应用需要根据需求来选择不同的协议,并且大致的了解了协议的内容。当然这中间还有许多细节需要我们来学习。