Node.js随手笔记(二):基本模块HTTP

前言

要理解Web服务器程序的工作原理,首先,我们要对HTTP协议有基本的了解。
HTTP(Hypertext Transfer Protocol, 超文本传输协议)是在网络上进行通信时所使用的协议方案,浏览器、服务器和相关的web应用程序都是通过HTTP相互通信的。HTTP就是现代全球网路中使用的公共语言。

HTTP概述

每天,都有数以亿万计的图片、html、文本文件、电影、音频、小程序和其他资源在网络上传输着。HTTP可以从遍布全球的服务器上把这些信息迅速、便捷的搬移到你面前的浏览器上。

HTTP使用的是可靠的数据传输协议,即使数据来自地球的另一端,它也能够确保数据在传输的过程中不会被损坏或者产生混乱。

联想到我们日常上网冲浪的需求,可知HTTP在其中扮演着举足轻重的角色。

那这时候我就很好奇了,客户端和服务器,或者web应用程序之间是如何利用HTTP进行通信的,HTTP又是如何完成其传输的工作。

客户端与服务器是如何通信的

服务器所使用的是HTTP协议,因此也经常被称为HTTP服务器。客户端向服务器发送HTTP请求,服务器会在HTTP响应中回送所请求的数据。如此,HTTP客户端和HTTP服务器共同构成了网络的基本组件。

《Node.js随手笔记(二):基本模块HTTP》

我们每天都在使用HTTP客户端。最常见的客户端就是浏览器,向服务器请求HTTP对象,并将这些对象显示在屏幕上。比如浏览一个网页(www.91wutong.com),浏览器会向服务器www.91wutong.com发送一条HTTP请求。服务器会去寻找所期望的对象,如果成功,就将对象、对象类型、对象长度以及其他一些信息放在HTTP响应中发送给客户端。

Web内容资源来自何方

我们日常请求的内容都是存储在服务器上的,服务器就是请求资源的宿主。最简单的web资源就是服务器文件系统中的静态文件。比如福星有一台static7.com的服务器,我每次把我要使用的图片发给他,让他放进服务器,只要他的服务器还在维护,这样我就可以在地球任意角落通过url访问得到。还有一些资源是根据需要生成内容的软件程序,比如股票交易,关键字搜索数据,或者在线购买商品。所有能够提供内容的东西都是web资源。

web事务是怎样工作的

一条HTTP事务由一条请求命令(从客户端发往服务器的)和一个响应结果(从服务器发回客户端的)组成。这种通信是通过名为HTTP报文的格式化数据块进行的。

《Node.js随手笔记(二):基本模块HTTP》

方法

HTTP支持多种不同的请求命令,这些命令被称为HTTP方法。每条HTTP的请求报文都包含一个方法。

  • GET 从服务器向客户端发送命名资源
  • PUT 将来自客户端的数据存储到一个命名的服务器资源中去
  • DELETE 从服务器中删除命名资源
  • POST 将客户端数据发送到一个服务器网关应用程序
  • HEAD 仅发送命名资源响应中的HTTP首部

状态码

每条HTTP响应报文返回时都会携带一个状态码。状态码是一个三位数字的代码,告知客户端请求是否成功,或者是否需要采取其他动作。

一些常见的HTTP状态码:

  • 200 ok
  • 302 Redirect 重定向 到其他地方去获取资源
  • 404 Not Found 没找到 无法找到这个资源
状态码范围描述
2xx200 – 206success
3xx300 – 305redirect
4xx400 – 415客户端error
5xx500 – 505服务器error

HTTP通信所使用的报文格式

《Node.js随手笔记(二):基本模块HTTP》

至此,我们已经了解到了HTTP通信需要客户端发送HTTP请求,服务器收到请求后,寻找期待的资源,返回响应对象。其中一来一回的请求与响应组成了一条http事务,这个通信过程是由名为HTTP报文的格式化数据块进行的。一个完整的HTTP报文包括:起始行,首部字段,主体。起始行说明了请求报文要做些什么,响应报文中出现了什么情况;首部字段都包含一个名字一个值,以冒号分隔,说明了请求或响应对象的类型数据量等信息;主体部分,请求主体中包含了要发送给服务器的数据,响应主体中装载了要返回给客户端的数据。

那通信过程大概是这样,可是我又在想了,客户端是怎样建立的这条通信呢,怎么就连通了可以互相来电呢?就像找对象一样,每天看着旁边的人和对象你侬我侬的,他们当初是怎么好上的呢。想要了解这一点,就要了解一下互联网协议。

互联网协议

在客户端向服务端发送报文之前,首先像日常打电话拨通对方的号码一样,建立客户端与服务器之间的TCP(传输控制协议)连接。从一个地方传送数据到另外一个地方,中间互相不知道彼此的物理位置,你不觉得这是很神奇的事情吗?是怎么做到的呢?这就是互联网协议可以做到的事情。

互联网的核心是一系列协议,总称为“互联网协议”。它们对电脑如何连接和组网,做出了详尽的规定。

层模型

互联网就像生活中的建筑物一样,是一个多层模型,一层依赖一层,每一层都依靠着下一层的支持,每一层又有着自己的功能。

关于互联网分层的说法很多,七层模型、五层模型,名字也不尽相同。但是从功能来说,名字叫什么无所谓,只要知道互联网是分成若干层次的就可以了。我们以五层来分析看:

  • 应用层
  • 传输层
  • 网络层
  • 数据链路层
  • 物理层(实体层)

最顶上的是用户接触到的应用层,最底层是实体层。中间三层自下而上是链接层、网络层、传输层。越往下面的层,越靠近硬件;越往上面的层越靠近用户。

每一层都是为了完成特定的功能,为了实现功能,就需要大家都遵循共同的规则,约定好协议。每一层里都定义了很多协议,这些协议统称为互联网协议,是互联网的核心。

我们日常接触到最多的是应用层,根本感觉不到下面的楼层。要想理解互联网,必须自下而上地理解每一层的功能。

物理层(实体层)

电脑要组网,第一件事要干什么?当然是把电脑连起来,可以用光缆、电缆、双绞线、无线电波等方式。实体层的作用就是把电脑连接起来的物理手段,作用是负责传送电信号。大家猜一下这里传输的信号会是什么东西呢?当然是二进制数据,0和1这样的电信号。

链路层

位于实体层的上方,确定了0和1的分组方式。解读0和1,多少个电信号为一组,每个信号位是什么意义。这里就很像接收电报后的翻译了,等等等等,多少个为一组,这一组是什么意思。

以太网协议

早期的时候,每家公司都有自己的电信号分组方式,后来名为以太网的协议占据主导地位,作为解读标准。
以太网规定,一组电信号构成一个数据包,叫做“帧”。每一帧分成两个部分:head 和 data。

  • 标头head:包含数据包的一些说明项,比如发送者,接收者,以及数据类型;长度固定为18字节
  • 数据data:数据包的具体内容;长度最小为46字节,最长为1500字节。

因此整个“帧”最短为64字节,最长为1518字节。如果数据很长,就必须分割成多个帧进行发送。

MAC地址

数据我知道,但是标头的信息怎么来的呢?
标头,包括了发送者和接收者的信息,那这两个是用什么做标识的呢?以太网规定,连入网络的所有设备都必须有“网卡”接口。数据包必须从一块网卡传送到另外一块网卡。网卡的地址,就是数据包的发送地址和接收地址,这就叫做MAC地址。每块网卡出厂的时候都有一个全世界唯一的MAC地址,长度为48个二进制位,通常以12个十六进制位表示。

广播的发送方式

一块网卡怎么会知道另一块网卡的MAC地址?(ARP协议)如果知道了这个地址,怎样才能把数据包准确送到接收方?
以太网采用了一种很“原始”的方式,它不是把数据点对点传过去,而是向本网络内所有计算机发送,让每台计算机自己拿数据包的标头信息去判断是否是接收方。这种方式就叫做“广播”。

有了数据包的定义、网卡的MAC地址、广播的发送方式、“链接层”就可以在多台计算机之间传送数据了。
但是所有的电脑人手一“包”去广播找对应的机器,效率低而且局限于发送者所在的子网络内。如果所有的机器都在一个子网络里,每个机器都会收到所有的数据包然后去比对MAC地址,这简直是灾难。互联网应该是由无数个子网络共同组成的一个巨型网络,这便导致了“网络层”的诞生。

网络层

它的作用是引进一套新的地址,使得我们能够区分不同的计算机是否属于同一个子网络。这套地址就叫做“网络地址”,简称“网址”。于是,每台计算机就有了两个地址,一个网络地址,一个MAC地址,两个地址之间没有相互的联系。网址帮助我们确定计算机所在的子网络,MAC地址则将数据包发送到子网络中的目标网卡。

从逻辑上来看,这两个地址的处理顺序是先网路地址后MAC地址了。

IP协议

规定网络地址的协议,叫做IP协议。被它定义的地址称为IP地址。网络上的每一台电脑,都会被分配到一个IP地址,这个地址分成两个部分,前一部分代表网络,后一部分代表主机。处于通过一子网络的电脑,它们IP地址的网络部分必定是相同的。

但是现在有个问题,但从IP地址上来看,我们无法判断网络部分。以192.168.20.8为例,他的网络部分,到底是前24位,还是前16位,这是看不出来的。那么怎么样才能从IP地址上判断两台机器是否在一个网路内呢?这还要用到另外一个参数“子网掩码”。

所谓“子网掩码”,就是表示子网络特征的一个参数。它在形式上等同于IP地址,也是一个32位的二进制数字,它的网络部分全部为1,主机部分全部为0。比如192.168.20.8,已知子网掩码为11111111.11111111.11111111.00000000写成十进制就是255.255.255.0。

知道了“子网掩码”,我们就能判断任意两个IP地址是否处在同一个子网络内。方法是将两个IP地址与子网掩码分别进行AND运算。(两个数位都为1,运算结果为1,否则为0),然后比较结果是否相同,如果是的话,就表明它们在同一个子网络中,否则就不是。

IP协议的作用主要有两个,一个是为每一台计算机分配IP地址,另一个是确定哪些地址在同一个子网络。

IP数据包

根据IP协议发送的数据,就叫做IP数据包,其中必定是要包括IP地址信息的。前面说过以太网数据包只包含MAC地址,并没有IP地址的栏位,这时候IP信息是怎么添加进数据包的呢?

我们可以把IP数据包直接放进以太网数据包的”数据”部分,因此完全不用修改以太网的规格。这就是互联网分层结构的好处:上层的变动完全不涉及下层的结构。

ARP协议

IP数据包放在以太网数据包里发送,所以我们必须知道两个地址,一个是对方的MAC地址,另一个是对方的IP地址。通常情况下,对方的IP地址是已知的(后文会解释),但是我们不知道它的MAC地址。

所以,我们需要一种机制,能够从IP地址得到MAC地址。

这里又可以分成两种情况。第一种情况,如果两台主机不在同一个子网络,那么事实上没有办法得到对方的MAC地址,只能把数据包传送到两个子网络连接处的”网关”(gateway),让网关去处理。

第二种情况,如果两台主机在同一个子网络,那么我们可以用ARP协议,得到对方的MAC地址。ARP协议也是发出一个数据包(包含在以太网数据包中),其中包含它所要查询主机的IP地址,在对方的MAC地址这一栏,填的是FF:FF:FF:FF:FF:FF,表示这是一个”广播”地址。它所在子网络的每一台主机,都会收到这个数据包,从中取出IP地址,与自身的IP地址进行比较。如果两者相同,都做出回复,向对方报告自己的MAC地址,否则就丢弃这个包。

总之,有了ARP协议之后,我们就可以得到同一个子网络内的主机MAC地址,可以把数据包发送到任意一台主机之上了。

传输层

有了MAC地址和IP地址,我们已经可以在互联网上任意两台主机上建立通信。

接下来的问题是,同一台主机上有许多程序都需要用到网络,比如,你一边浏览网页,一边与朋友在线聊天。当一个数据包从互联网上发来的时候,你怎么知道,它是表示网页的内容,还是表示在线聊天的内容?

“传输层”的功能,就是建立”端口到端口”的通信。相比之下,”网络层”的功能是建立”主机到主机”的通信。只要确定主机和端口,我们就能实现程序之间的交流。

UDP协议

现在,我们必须在数据包中加入端口信息,放在IP数据包之中,而前面说过,IP数据包又是放在以太网数据包之中的,所以整个以太网数据包现在变成了下面这样:

《Node.js随手笔记(二):基本模块HTTP》

这就是UDP协议。简单易实现,但是可靠性较差,一旦数据包发出,无法知道对方是否收到。为了解决这个问题,提高网络可靠性,TCP协议就诞生了。

TCP协议

TCP协议非常复杂,但可以近似认为,它就是有确认机制的UDP协议,能够确保数据不会遗失,每发出一个数据包都要求确认。如果有一个数据包遗失,就收不到确认,发出方就知道有必要重发这个数据包了。

只要建立了 TCP 连接,客户端和服务器之间的报文交换就不会丢失、不会被破坏,也不会在接收时出现错序了。

应用层

应用程序收到”传输层”的数据,接下来就要进行解读。由于互联网是开放架构,数据来源五花八门,必须事先规定好格式,否则根本无法解读。

“应用层”的作用,就是规定应用程序的数据格式。

举例来说,TCP协议可以为各种各样的程序传递数据,比如Email、WWW、FTP等等。那么,必须有不同协议规定电子邮件、网页、FTP数据的格式,这些应用程序协议就构成了”应用层”。

这是最高的一层,直接面对用户。它的数据就放在TCP数据包的”数据”部分。因此,现在的以太网的数据包就变成下面这样。

《Node.js随手笔记(二):基本模块HTTP》

一个实例:访问网页

《Node.js随手笔记(二):基本模块HTTP》

node基本模块HTTP

    原文作者:Liebe
    原文地址: https://segmentfault.com/a/1190000016294135
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞