Conclusions on Application Layer
================================

## DNS

在实际应用中，通过IP来访问是不太可能的，因为没人记得住那么多IP地址(据说曾经人们以记得住的IP地址数量，来衡量他们的学术水平)。所以就像要给变量和函数取名一样，给IP地址也可以取一个有意义的名字。这就是域名(Domian Name)

### 域名的层次结构

最开始的时候，人们给IP地址取名也像给自己的孩子取名一样，反正就随便起。那时候网络还不是很多，所以问题不大。后来，互联网发展迅速，出现了很多很多IP，随便起名就容易重名，还不好管理。于是就像各个机构的科、处、室一样，出现了域名的层次结构。

那么问题来了，为什么IP的名字叫域名呢？

这是因为域名的层次结构里面，每一层又称为一个域。如tongji.edu.cn中，

+ `cn`是顶级域名
+ `edu`是顶级域名`cn`下的二级域名
+ `tongji`是二级域名`edu`下的三级域名
+ 三级域名下面还可以有区分不同服务的域名，如`mail`, `www`, `dns`...

简单说来，顶级域名(TLD, Top Level Domain)又分为国家顶级域名(nTLD)和通用顶级域名(gTLD)

+ 国家顶级域名: 如`cn`, `us`, `uk`...
+ 通用顶级域名: 
	- `com`: 公司企业
	- `org`: 非盈利机构
	- `net`: 网络服务机构
	- `edu`: 美国专用的教育机构
	- ...

一旦某个单位拥有一个域名，就可以在其下进一步划分子域名，如我国就可以自己划分二级域名为类别域名和行政区域名:

+ 类别域名: 
	- `ac`: 科研机构
	- `edu`
	- `net`
	- `gov`
	- ...
+ 行政区域名

而像是同济大学拥有了自己的域名`tongji.edu.cn`后，就可以在其下划分下一级的`www`域名、`mail`域名、`dns`域名等

最后要说明的是，域名的层次结构和IP地址的子网没有任何关系，尽管有时为了管理两者往往是匹配的。如`www.tongji.edu.cn`的IP地址并不一定是`tongji.edu.cn`对应IP下的子网。这是因为域名是按照机构的组织来进行划分的，而IP地址是按照ISP来划分的。

### 域名服务器的层次结构

我们平时网上冲浪时，都是通过域名来访问各个网站的(当然喜欢装逼直接输IP地址的除外)。那么就产生了一个问题，如何完成从域名到IP地址的解析呢？

答案当然是域名服务器，但是这里的问题就像路由器一样，正如路由器不可能装下全互联网所有的路由表，域名服务器也不可能装下全网的域名与IP的对应关系。

所以这里采用的是分层次的域名服务器，而这就构成了一个联机分布式数据库系统。一般说来，域名服务器分为以下的层次：

+ 根域名服务器: 是最高层次的域名服务器。查询根域名服务器也并不能让你知道所有域名所对应的IP地址，而只是告诉你下一步应该查询的域名服务器地址。这是因为，根域名服务器只知道所有的顶级域名服务器的域名和IP地址。
+ 顶级域名服务器：负责管理在该顶级域名下注册的所有二级域名。查询顶级域名服务器可以返回下一步应该查找的域名服务器的IP地址。
+ 权限域名服务器：是各个机构负责一个_区_(zone)的域名服务器。这里的_区_和_域_并不是一个概念。例如`tongji.edu.cn`是一个域，在其下可以划分多个区，像是汽车学院一个区(`auto.tongji.edu.cn`),数学院一个区(`math.tongji.edu.cn`)，这些区都可以有自己的域名服务器，即权限域名服务器。很明显，这里的_区_是_域_的子集。
+ 本地域名服务器：也叫默认域名服务器。请求DNS服务时，首先访问的就是本地域名服务器。

在以上层次结构的基础上，给出域名解析的过程

+ 主机向本地域名服务器的查询: 递归查询。即如果本地域名服务器不知道被查询的IP地址，则作为DNS客户再向其他根域名服务器发出查询报文(基于UDP)。
+ 本地域名服务器向根域名服务器的查询: 迭代查询。即根域名服务器只是告诉本地域名服务器下一步要查询的域名服务器的IP，然后让本地域名服务器自己进行下一步的查询。

此外，为了提高效率，肯定有用到高速缓存的思想--本地域名服务器以及主机本地都缓存了一段时间内查询过的域名。

## 文件传输协议

文件传输协议有两个: 基于TCP的FTP(File Transfer Protocol)以及基于UDP的简单文件传输协议(TFTP, Trivial File Transfer Protocol)

### FTP

FTP是使用客户服务器的方式，服务器端拥有一个主进程，用于监听接受新的客户连接请求。此外还有若干从属进程，负责处理单个请求。

+ 主进程只负责接受新的连接请求，端口号21
+ 接收到新的连接请求后，启动一个新的从属进程，负责处理单个请求。这里使用一个新的端口，用于建立数据传送连接。
+ 这样，服务器和客户之间就存在了两个并行的TCP连接: 一个控制连接和一个数据连接。由于FTP使用了两个不同的端口号，因此数据连接和控制连接不会发生混乱。

### TFTP

TFTP是基于UDP的文件传输协议。可以用于下面的情况:

+ 由于UDP多播的特点，当需要将程序或文件同时向许多机器下载时往往使用TFTP
+ TFTP更简单，不需要硬盘存储程序。只需要固化了TFTP, UDP, IP的小容量只读存储器即可。

TFTP的工作过程很像停止等待协议，即发送完一个文件块后，须要等待确认。

TFTP的工作过程中也类似FTP，需要两个不同的端口。一个端口(端口号69)用于接受新的TFTP请求，之后TFTP服务器选择一个新的端口和客户进程完成通信。


## `TELNET`

TELNET是一个简单的远程终端协议。通过TELNET用户可以远程登录到另一台主机上(类似ssh，但是ssh由于有加密算法，所以更安全)。

TELNET使用端口号23，ssh(Secure Shell, 安全外壳协议)使用端口号22。

TELNET要实现将用户在本地的击键传到远地主机，同时使远地主机的输出通过TCP连接返回用户屏幕上。由于不同计算机操作系统的差异，两台计算机的控制命令等处理往往是不一样的，如不同主机对换行符的处理方式也不同。TELNET就需要适应各种计算机和操作系统之间的差异。

TELNET使用了网络虚拟终端(NVT, Network Virture Terminal)定义了数据和命令应该怎样通过互联网。

+ 客户击键时，将命令转换成NVT格式，并送交服务器
+ 服务器将收到的数据和命令个从NVT格式转换成远地主机所需的格式
+ 向用户返回数据是上述过程的逆过程

## 万维网

万维网是一个非常伟大的思想。上世纪60年代就有人提出万维网的思想了:创建一个全球化的大文档，文档的各个部分分布在不同的服务器中。通过激活称为链接的超文本项目，例如研究论文里的参考书目，就可以跳转到引用的论文。现在，万维网是一个大规模联机式的信息储藏所。

考虑要实现上面的功能，需要的一些底层接口。

首先，既然文档的各个部分分布在不同的主机中，我们需要一种方式来唯一定位不同主机中的不同文档以及相同主机中的不同文档(超文本)。这种方式最好是具有一定格式的，像IP地址或是dns域名一样，以便于实现。

在定位各个主机中的文档(超文本)后，需要有一种统一的协议来传输这种超文本。这有点类似于FTP，却又不尽相同。ftp传输的文件只是传文件本身，而传输超文本时，超文本中链接的图片等数据也需要一同传输。倘若使用ftp，传输的结果只是链接的锚(anchor)，并不具有什么意义。

最后还有一个问题，不同的人编辑的超文本会具有不同的风格，会采用不同的文件格式。这些不同格式的文件解析方式显然是不一样的(比如你也可以.doc文件中插入超链接，这从广义来讲也是一个超文本了)。这对于万维网客户端的显示显然是不方便的。因此，万维网传输的超文本文档需要一个统一的格式。

此外，由于超文本文档是由用户编辑，并放在自己的服务器上(或是博客等网站上)。怎么让其他用户找到这些文档也是一个问题。

上面提到的几个问题，就构成了万维网的核心内容:

+ 为了定位不同主机中的文档，万维网采用统一资源定位符(url, Uniform Resources Locator)
+ 为了传输超文本文档，万维网采用超文本传输协议(HTTP, HyperText Transfer Protocol)
+ 为了客户端可以方便地显示不同的超文本文档，万维网定义了超文本文档的格式为超文本标记语言(HTML, HyperText Markup Language)
+ 为了用户找到分布在不同地区的超本文文档，出现各种各样的万维网搜索工具。

### 统一资源定位符

为了唯一的标记互联网上不同主机的不同文件，一个很自然的想法是首先利用IP地址，唯一地标记互联网上某台主机，然后利用该主机上端口号和文件路径，来唯一标记某个文件。

此外，由于访问不同对象的协议不同，url还需要指定当前使用的协议类型。这就组成了url的基本格式:
<p align="center"> <协议>://<主机>:<端口>/<路径> </p>

实际上，不只是超文本传输协议使用url定位资源，使用ftp等其他应用程序时，也使用url来定位需要获取的资源

### 超文本传输协议

HTTP定义了万维网客户进程(浏览器)怎么向万维网服务器请求万维网文档，以及服务器如何将文档传输给浏览器。

HTTP是基于TCP的，这样可以做到数据的可靠传输。

+ 万维网服务器进程不停地监听TCP的80端口，以便发现是否有浏览器发出连接请求。
+ 一旦建立了TCP连接，浏览器向服务器发出浏览某个页面的请求，服务器接着返回请求的页面
+ 释放TCP连接

HTTP具有以下的特点:

+ 面向事务的(抄书，不是很懂
+ 无连接的。是说虽然HTTP下面的TCP是有连接的，但是HTTP的确是无连接的。通信的双方在不需要先建立HTTP连接的情况下就可以进行通信。
+ 无状态的。同一个客户第二次访问同一服务器上的页面时，服务器的响应与第一次相同。因为服务器不记得这个客户（cookie除外

HTTP/1.0 与 HTTP/1.1

+ HTTP/1.0 采用非持续连接。客户端每请求一个万维网文档，需要建立连接的三报文握手(请求报文作为第三个报文的数据)以及服务器端响应的文档，共两倍的往返时间RTT。这样如果一个主页上有多个链接的对象，如一个超文本文档链接了很多图片，所有这些链接对象的下载都需要两倍RTT时间的开销。

+ HTTP/1.1 改进了这点，采用持续的连接。即客户端和服务器在一次响应结束后，仍然在一段时间内保持连接，这样，同一个客户可以继续在这条连接上传送后续的HTTP请求报文和响应报文。HTTP/1.1 的持续连接还有非流水线方式以及流水线方式。(显然流水线方式效率最高)

### HTML

(这tm是个花瓶？

### 一些其他问题

万维网的请求是非常频繁的。所以可以猜到，万维网的实现中，有利用高速缓存的思想。

万维网高速缓存又称为代理服务器。简单说来，代理服务器可以为一个网络中的用户存储一段时间内访问过的资源，用户在访问互联网时，首先访问代理服务器，只有当代理服务器中没有存储该请求与响应，才代表用户去访问互联网中的源点服务器。

在校园网这种带宽受限的网络中，使用代理服务器可以使相当大一部分通信量局限在校园网内部，减小了互联网的时延。

## 电子邮件

一个电子邮件系统需要三个主要组成构件

+ 用户代理
+ 邮件服务器
+ 邮件发送协议以及邮件读取协议

在邮件发送的过程中，邮件服务器往往要同时充当客户和服务器。如我(使用163邮箱)要发送邮件给同济大学的邮箱(mail.tongji.edu.cn)

+ 首先发送邮件给163邮箱的邮件服务器(端口号25)
+ 163邮箱的邮件服务器收到我的邮件，将邮件临时存在在邮件缓存队列中。等待发送给接收方的邮件服务器
+ 163邮箱的邮件服务器作为SMTP的客户，发送邮件给同济邮箱的邮件服务器。这里，邮件不会在互联网中的某个中间邮件服务器落地
+ 同济邮箱的服务器将收到的邮件放入收件人的用户邮箱中，等待用户读取。

### 邮件发送协议SMTP(简单邮件传送协议)

使用SMTP发送邮件的过程

+ 建立连接。首先需要在客户端和邮件服务器之间建立TCP连接。SMTP不使用中间的邮件服务器，连接总是在发送方和接收方之间直接建立。
+ 邮件传送。
	- 从MAIL命令开始。若服务器已准备好接收邮件，则回答'250 OK'
	- 之后跟着一个或多个REPT(recipient)命令，指明收件人。若指定的收件人在接收方的系统内，则返回'250 OK'。若无此用户，则返回'550 No such user here'。其目的是为了节约通信资源，防止出现发送了很长的邮件后才知道地址错误的情况。
	- DATA命令传输邮件的内容。
+ 连接释放: SMTP发送QUIT命令。

### 邮件读取协议

+ POP3(邮局协议, Post Office Protocol version 3)。只要用户从POP3服务器读取了邮件，POP3服务器就把该邮件删除了。因此，就会比较不方便。

+ IMAP协议(网际报文存取协议, Internet Message Access Protocol)。与POP3不同，是一个联机协议，用户操作邮件服务器的邮箱就像在自己的电脑上一样。只有用户需要打开某个邮件时，该邮件才传到用户的计算机上。缺点是如果用户不删除，它就一直保存在服务器邮箱中。

### 基于万维网的电子邮件

实际上，我们收发邮件时，都是使用浏览器，而没有安装特定的电子邮件用户代理。

而用户在浏览器中浏览各种信息时需要使用HTTP协议，因此在浏览器和互联网上的邮件服务器之间传送邮件时，仍然使用HTTP协议。只有在各个邮件服务器之间传送邮件时，才使用SMTP协议。
