计算机网络之应用层详解
应用层是tcp/ip五层模型的最高层,用于为用户提供服务。从应用层看通讯,应该是两个通信端点之间进程之间的逻辑连接。例如:A主机访问了B主机,对于二者而言,虽然通信过程中存在多个物理链路。但是对应用层而言,他仅仅关注A程序到B程序的连接。
需要注意的是:因为应用层作为最高层的协议集合,所以对应用层协议的添加和去除显得更容易,并不用考虑上层协议的耦合。
标准的应用层协议:
一些我们使用的协议如:http,已经有标准因特网管理,使用中需要严格按照规范。
非标准的应用层协议:
而实际上我们自己可以约定应用层通信之间的一些细节,自己编写非标准的应用层程序,如果仅仅是私人使用,这样的非标准也是可行的。
通讯模式:
客户-服务器(c/s)模式:
通信两端扮演不同角色,客户端需要向一台服务器发送请求,服务器应该一直运行,为客户端提供服务。
对等模式(p2p):
这种模式并不需要一台提供服务的服务器,通信两端是对等的,即可能提供服务,也可能接受服务。
混合模式:
把前两种有点混合的通信模式
客户-服务器模式(c/s):
API(application programming interface):
对计算机而言,总需要一些指令去告诉计算机该怎么做,例如,键盘和显示器,计算机通过键盘的输入读取所需信息,并且在显示器显示,这样的操作实际上发生在我们和应用程序和操作系统之间,操作系统提供了这些操作需要要的api,也就是说,如果有这样一套应用层协议的程序,那么也需要操作系统来解读这样的程序,实际上,操作系统封装了底层协议为应用层提供服务器,包括TCP/ip协议。这样的一套为应用层提供服务的接口即使API(application programming interface),三种这样的网络api分别是:socket(套接字) 接口,Transport Layer Interface,TLI(传输层接口)和Stream(流接口)。
对于socket觉得比较抽象,暂且把Socket理解为一种应用程序创建的抽象数据结构。
也就是说应用程序进程通过对socket访问,来请求和接受响应,其余的可以理解为操作系统以及内置的TCP/IP的工作。
socket地址:
有了接口,数据结构,还需要一个地址来区别两个通信端点之间的位置。
地址由一个32位IP地址和一个16位端口号组成,用:隔开
例如:210.38.136.66:8049
前面的ip是用来区别哪台主机,端口是用来区别那个进程,也就是是浏览器还是你的QQ。
本地Socket地址:
对服务器和客户一样的,都有操作系统提供一个ip地址,对于服务器,端口如果是标准进程,如http,那么就是80,已经事先分配好,对于客户端,发送请求的端口应该是一个临时的端口。
远程Socket地址:
对服务器程序而言,他并不知道稳定的远程通信地址,因为他每天为千千万万用户提供服务,对于客户端程序而言,他可能已经知道需要发送到那个服务器地址获取服务。
cs模式使用来自传输层的服务,比如无连接不可靠,但是速度佳的udp服务。也会使用,面向连接可靠的字节流传输协议tcp协议。也可以是结合两种的sctp协议。
客户-服务器模式的应用:
Web和http:
应该说,当今web两大特点,分布式,可链接。
这使得这样一个关系就像一个蜘蛛网。
浏览器:
这个是我们访问web的一个应用程序。
它包含三个部分,
控制程序:控制和用户以及其他部分的程序。
解释程序:最常见的是运行了js脚本的页面,必须有内置解释器来解释js语言,提供dom接口。
客户协议:浏览器包含了各种各样的协议。
web服务器:Apache,nginx.
URL(uniform Resource locator)统一资源定位符:
说的高大上。
其实本质就是用来说明四个东西:使用了什么协议,哪个主机,哪个端口,哪个页面。
所以就是这样:https://github.com/turingwu/
https :协议
github.com :host(通过dns解释后即使前面的sock地址:111.111.111.111:111)
turing:路径。
http1.1版本之前是非持续的连接,他和他之后是默认持续连接。
用tcp三次握手为例子
非持续连接:
这会发现,每个一个请求都需要重复三次握手进行连接。
可持续连接:
http是以报文方式传输的:
请求报文格式:
例子:
GET /usr/bin/image1 HTTP/1.1
Accept: image/gif
aaa
请求方法:
方法 | 动作 | 方法 | 动作 |
GET | 获取文档 | TRACE | 回送输入请求 |
HEAD | 请求文档的信息,而不是文档本身 | DELETE | 删除页面 |
PUT | 从客户端向服务器发送文档 | CONNECT | 预留 |
POST | 客户端向服务器发送信息 | OPTIONS | 询问可用选项 |
请求头部键:
头部 | 描述 | 头部 | 描述 |
User-agent | 标示客户端程序 | Host | 客户端主机端口号 |
Accept-charset | 给出客户端接受的字符 | Date | 当前日期 |
Accept-encoding | 客户端可以处理的编码方案 | Upgrade | 首选协议 |
Accept-language | 给出客户端处理的语言 | Cookie | 给你cookie |
Authorization | 客户端许可 | If-Modified-Since | 判断事非指定日期后被修改 |
响应报文:
响应头部键名称:
头部 | 描述 | 头部 | 描述 |
Date | 当前日期 | Content-Length | 给出文档长度 |
Upgrade | 首选的通信协议 | Content-Type | 指定媒体类型 |
Server | 给出服务器信息 | Location | 指出新建或者移动后文档位置 |
Set-Cookie | 服务器要求客户存层cookie | Accept-Ranges | 服务器会接受的请求字节范围 |
Content-Encoding | 编码规范 | Last-modified | 给出上次改变的日期和时间 |
Content-Language | 指定语言 |
例子:
HTTP/1.1 200 OK
Server: nginx/1.4.4
Date: Tue, 22 Nov 2016 05:48:13 GMT
Content-Type: image/gif
Content-Length: 0
Last-Modified: Wed, 06 Jan 2016 02:38:55 GMT
Connection: keep-alive ETag: "568c7e3f-0"
Accept-Ranges: bytes
Cookie:
http是面向无连接的,通过服务器返回set-cookie来设置cookie,这样下次客户端请求服务器时就可以知道上一次状态的信息。
web高速缓存代理:代理服务器:
用于保存最近的文档,这样无需访问目标服务器即可快速获得。
FTP协议:
文件传输协议(File Transfer Protocol,FTP)是Tcp/ip标准机制,用于将文件从一个主机复制到另一个主机。两个系统之间的传输需要太多约定,然而ftp简单的灵活的解决了。
在大文件传输上,ftp是更好的选择。
连接结构:
也就是FTP协议使用过程中,有两个进程被打开,控制进程,也就是21端口,用于协调控制一些操作和预定一些提前的准备,开始文件传输时使用数据传输进程。
控制传输过程中,有客户主机发送ascii字符集,一般控制的字符集作用如下:
命令 | 参数 | 说明 |
ABOR | 放弃之前的指令 | |
CDUP | 改变到上级父目录 | |
CWD | 目录名 | 改变目录(类似cd) |
DELE | 文件名 | 删除目录 |
MKD | 目录 | 创建目录 |
PASS | 密码 | 密码 |
LIST | 目录 | 列出目录下的东东 |
PASV | 服务器选择一个端口 | |
PORT | 端口名 | 客户端选择一个端口 |
PWD | 显示当前目录 | |
QUIT | 退出登陆 | |
RETR | 文件名 | 获取文件 |
RMD | 目录名 | 删除目录 |
RNFR | 文件名 | 标示一个被重命名文件 |
RMD | 目录名 | 删除目录 |
RNTO | 文件名 | 重命名文件 |
STOR | 文件名 | 存文件 |
STRU | F,R,P | 定义数据组织(F:文件,R:记录,P:页面) |
TYPE | A,E,I | 文件类型(A:ASCII,E:EBCDID,I:图像) |
USER | S,B,C | 定义传输方式(S:流,B:块,C:压缩) |
还有一个MODE S,B,C 定义传输方式(S:流,B:块,C:压缩)
命令发出以后,服务器端会有响应,部分响应约定如下:
编码 | 说明 | 编码 | 说明 |
125 | 数据连接开始 | 250 | 请求文件成功 |
150 | 文件状态良好 | 331 | 用户名成功:密码需要 |
200 | 成功 | 425 | 无法打开连接 |
220 | 服务就绪 | 450 | 文件不可用 |
221 | 服务关闭 | 452 | 动作放弃:磁盘不足 |
225 | 数据连接开始 | 500 | 语法错误:命令无效 |
226 | 关闭数据连接 | 501 | 参数变量语法错误 |
230 | 登陆成功 | 530 | 用户未登陆 |
数据连接:
数据连接进程中,服务器使用标准的端口20,首先有客户端发起,使用一个临时端扣被动打开数据连接。客户使用PORT命令来声明自己使用的端口,提前准备,客户端需要在数据连接开启前书名三种约定,数据结构:STRU命令定义,文件结构:TYPE命令也约定,文件类型:MODE:命令约定。
例子:
我使用的系统是Fedora(radhat系的),尝试用liunx下的ftp来获取文件:
首先ftp ip地址来连接到远程服务器
此时,需要输入用户名和密码:
完成后登陆成功,注意服务器返回的220,331,230正是上面的状态码,而ftp使用的指令已经进行了封装,常用命令如下:
ls 列出远程机的当前目录
cd 在远程机上改变工作目录
lcd 在本地机上改变工作目录
ascii 设置文件传输方式为ASCII模式
binary 设置文件传输方式为二进制模式
close 终止当前的ftp会话
hash 每次传输完数据缓冲区中的数据后就显示一个#号
get(mget) 从远程机传送指定文件到本地机
put(mput) 从本地机传送指定文件到远程机
open 连接远程ftp站点
ls命令显示超时,421状态码。
用open重新连接,并且下载一个文件
自此,完成第一个数据连接。
可想而之,即使是ls这样的命令也是遵循了上面ftp的命令规范,可以想象得到,底层必然发生了类是于:
USER hdcpptd(获取用户)
PASS ******** (输入密码)
PORT 10090 (客户端和服务器说开启数据端口10090)
TYPE EBCDIC(定义类型)
STRU R..
等等这样的ftp协议规范
邮件协议:
架构:
三个代理:
用户代理(User Agent)UA
邮件传输代理(Mail Transfer Agent)MTA
邮件访问代理(Mail Access Agent)MAA
UA可以理解为一个应用程序,假设左边发了一封邮件给右边,那么应该是这样一个架构。
这里面有两台邮件服务器,实际上发生在同一个邮件服务器上,但是流程不会变,当邮件服务器作为一端接受邮件的时候,那么此时有MTA服务器接受,然而这里面这个服务器也必须得充当客户端角色,他必须给目标发送邮件。作为邮件接受的用户,因为他的电脑并非服务器,不可能一直等待邮件到来,所以,有MAA程序发送请求去自己的邮件服务器获取邮件。
地址:
邮箱地址一般是这样
本地用户地址@邮件服务器地址
简单邮件传输协议:SMTP
MTA传输过程中使用SMTP(简单邮件传输协议),MAA(使用POP/IMAP协议)
用两种协议是因为本身这两个动作的作用是不同的,SMTP中需要定义发送地址所向,POP/IMAP主要作用就是获取,也就是自报家门。
SMTP发送中,需要一些指令协作:
协议定义了这样一些指令:
关键词 | 变量 | 说明 |
HELO | 发送者的主机名 | 用于识别自身 |
MAIL FROM | 发信人 | 识别发信人 |
RCRT TO | 收信人 | 识别收信人 |
DATA | 邮件主题内容 | 发送内容 |
QUIT | 离开 | |
RSET | 放弃当前邮件事务 | |
VRFY | 收件人名字 | 验证收件人地址 |
NOOP | 检测收件人状态 | |
TURN | 交换收件人收信人 | |
EXPN | 邮箱列表 | 扩增邮箱列表 |
HELP | 以参数形式发送命令信息 | |
SEND FROM | 收信人 | 只发送到终端 |
SMOL FROM | 收信人 | 发送到终端或者邮箱 |
SMAL FROM | 收信人 | 发送到终端和邮箱 |
响应约定码:
肯定完成答复
211 系统状态
214 帮助报文
220 服务就绪
221 服务关闭
250 请求完成
251 用户不是本地,报文转发
肯定中间服务
354 开始邮件输入
暂时否定
421 服务不肯用
450 邮箱不可用
451 命令终止:本地错误
452 空间不足
永久否定
500 无法识别
501 参数或者变量错误
502 命令未执行
503 命令序列不正确
504 命令暂时不能执行
550 邮箱不可用
551 不用不是本地的
552
553
554 事务失败
POP和IMAP协议:
IMAP协议比pop更复杂强大
邮件传输只能发送nav7,和ascii格式报文,通过MIME协议扩展辅助以后支持非ASCII数据。
MIME协议作为头部安插在了邮件头部中