网络协议分层
经典五层模型
- 物理层:主要作用是定义物理设备(硬件设备,网卡等)如何传输数据
- 数据链路层:主要作用是在通信的实体间建立数据链路链接
- 网络层:主要作用是为数据在结点之间传输创建逻辑链路
- 传输层:向用户提供端到端的服务(End-to-to-End),向高层屏蔽了下层数据通信的细节
- 应用层:为应用软件提供服务
HTTP的三次握手
HTTP本身只有REQUEST和RESPONSE,即响应和请求,无法和服务器构成连接,是通过TCP实现客户端和服务器端的连接。
URI,URL,URN
URI
Uniform Resource Identifier–统一资源标识符,用来唯一标志互联网上的信息资源,包括URL和URN。URI的最常见的形式是统一资源定位符(URL),经常指定为非正式的网址。更罕见的用法是统一资源名称(URN),其目的是通过提供一种途径。用于在特定的命名空间资源的标识,以补充网址。通俗地说,URL和URN是URI的子集,URI属于URL更高层次的抽象,一种字符串文本标准。可以简单理解为URL和URN是URI的实现。URL是统一资源定位器,它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源,而URN,统一资源命名,是通过名字来标识资源。
统一资源标志符URI就是在某一规则下能把一个资源独一无二地标识出来。
拿人做例子,假设这个世界上所有人的名字都不能重复,那么名字就是URI的一个实例,通过名字这个字符串就可以标识出唯一的一个人。
现实当中名字当然是会重复的,所以身份证号才是URI,通过身份证号能让我们能且仅能确定一个人。
那统一资源定位符URL是什么呢。
也拿人做例子然后跟HTTP的URL做类比,就可以有:动物住址协议://地球/中国/浙江省/杭州市/西湖区/某大学/14号宿舍楼/525号寝/张三.人可以看到,这个字符串同样标识出了唯一的一个人,起到了URI的作用,所以URL是URI的子集。URL是以描述人的位置来唯一确定一个人的。在上文我们用身份证号也可以唯一确定一个人。对于这个在杭州的张三,我们也可以用:身份证号:123456789来标识他。所以不论是用定位的方式还是用编号的方式,我们都可以唯一确定一个人,都是URl的一种实现,而URL就是用定位的方式实现的URI。
回到Web上,假设所有的Html文档都有唯一的编号,记作html:xxxxx,xxxxx是一串数字,即Html文档的身份证号码,这个能唯一标识一个Html文档,那么这个号码就是一个URI,即能实现对统一资源的标志的方法就可以叫做URI,而URL只是URI的其中一种实现
URL
Uniform Rssource Locator–统一资源定位器,URL是URI的其中一种。
URL代表资源的路径地址,通过URL找到资源是网络位置进行标志,如:
URN
Uniform Resource Name–统一资源名称
通过资源的名称去定位唯一资源,而不是通过路径去定位。比如原来的html文件换了路径,这时候访问就会出现404,而如果使用URN就仍可以继续访问
HTTP报文格式
HTTP报文是在HTTP应用程序之间发送的数据块。
报文组成
HTTP报文的三个部分:
- 起始行:报文的第一行就是请求行。在请求报文中,首行的信息包括请求方法类型,请求资源路径,HTTP版本等信息;在响应报文中,首行的信息包括HTTP版本号,状态码等
- 首部:起始行后面有零个或多个首部字段。每个首部字段都包含一个名和一个值,为了便于解析,两者之间用冒号分隔。首部以一个空行结束
- 主体:空行之后就是可选的报文主体了,其中包含了所有类型的数据。请求主体中包括了要发送给Web服务器的数据;响应主体装载了要返回给客户端的数据。起始行和首部都是文本形式且都是结构化的,而主体则不同,主体中可以包含任意的二进制数据(比如图片,音频等)
HTTP请求报文
请求首行
请求首行由方法字段,URL字段和HTTP协议版本三个字段组成,它们之间用空格分隔,
如 GET www.baidu,com HTTP/1.1.
请求方法包括GET,POST,DELETE,PUT…等
请求头部
请求头部为报文添加了一些附加信息,由key-value组成,每行一对,名和值之间用冒号分隔
常见请求头:
请求头 | 说明 |
---|---|
Host | 请求的服务器的地址 |
User-Agent | 发送请求的应用程序名称 |
Connection | 指定与连接相关的属性,如Connection:Keep-Alive |
Accept-Charset(字符集) | 通知服务端可以发送的编码格式 |
Accept-Encoding(字符编码) | 通知服务端可以发送的数据压缩格式 |
Accept-Language | 通知服务端可以发送的语言 |
请求头部最后会有一个空行,表示请求头部结束,接下来为请求正文,这一行非常重要
请求正文
这是可选部分,比如GET请求就没有请求正文。下面讲下POST请求中的请求正文。
1)创建web应用,新建表单
<form action="/test.jsp" method="post">
用户名:<input type="text" name="username"/></br>
密码:<input type="password" name="password"/></br>
<input type="submit" value="提交"/>
</form>
- 启动Tomcat发布应用,浏览器输入url
- 网页中填入用户名和密码
在请求正文会看到:
username=Reyco&password=112233
GET请求不存在请求正文,请求参数放在URL后面
HTTP响应报文
HTTP响应主要由状态行,响应头部,响应正文三部分组成
状态行
响应状态行由三部分组成,HTTP协议版本,状态码,状态码描述,之间由空格分隔。
状态代码由三位数字构成,第一个数字设置了响应的类别:
- 1xx:指示信息–表示请求已被接收,继续处理
- 2xx:成功-表示请求已被接收和处理
- 3xx:重定向–要完成请求必须更进一步的操作
- 4xx:客户端错误–请求有语法错误或请求无法实现
- 5xx:服务器端错误–服务器未能实现合法的请求
响应头部
常见响应头部
响应头 | 说明 |
---|---|
Server | 服务器应用程序软件的名称和版本 |
Content-Type | 响应正文的类型(是图片还是二进制字符串) |
Content-Length | 响应正文长度 |
Content-Charset | 响应正文使用的字符集 |
Content-Encoding | 响应正文使用的数据压缩格式 |
Content-Language | 响应正文使用的语言 |
响应正文
服务器端返回给客户端的信息
使用Node.js创建Web服务器
server.js
const http = require('http')
http.createServer(function (request, response) {
console.log('request come', request.url)
response.end('123')
}).listen(8888)
console.log('server listening on 8888')
进入cmd命令,切换到server.js所在文件
执行node server.js
效果
访问localhost:8888,即可看到响应成功