Web Base (二) Common Protocols and Standards


常见协议和标准

概述:简单介绍 DNS 协议、TCP/IP 协议、HTTP 协议和 Java Web 开发中的 Servlet。

DNS 协议

DNS 协议的作用是将域名解析为 IP。

我们知道网络上每个站点都是使用 IP 来确定的,所以想要访问一个网站就需要先知道它的 IP,但是 IP 记起来不方便,所以就设计了比较好记的域名来代替 IP。

而负责处理域名和 IP 之间的对应关系的就是 DNS 协议,考虑到网上有非常多的域名,如果使用客户机去处理会比较慢,而且域名和 IP 之间的对应关系也是不稳定的,时常在变化,所以就需要专门将域名解析为 IP 的服务器,这就是 “DNS 服务器”。

我们把域名发送给 DNS 服务器,他就会返回给我们 IP 地址,比如 windows 中可以使用 nslookup 来查看 DNS 解析的结果:

世界各地有很多 DNS 服务器,ISP 会给我们提供默认的 DNS 服务器,也有一些大型公用 DNS 服务器可以使用,比如 Google 的 8.8.8.8 和国内的 114.114.114.114

我们直接访问的 DNS 服务器叫 本地 DNS 服务器,它本身也没有域名和 IP 的对应关系,在我们发出请求的时候它会从主 DNS 服务器获取然后保存到缓存中,下次再有相同的域名请求直接从缓存中获取就可以了。

TCP/IP 协议与 Socket

TCP/IP:(传输控制协议/英特尔互联协议)这两个协议经常放在一起,但他们是不同的,所起的作用也不一样。

  • IP 协议是用于查找地址
  • 具体传输工作由 TCP 完成

TCP 在传输之前需要进行三次沟通,一般称为 “三次握手”,传完数据断开时要进行四次沟通,称为 “四次挥手”。

要理解这个过程需要理解 TCP 的两个序号和三个标志位的含义。

  • seq:sequence numbe 的缩写,表示所传数据的序号。TCP 传输时每一个字节都要有一个序号,发送数据时会将数据的第一个序号发送给对方,接受方会按序号检查是否接收完整,如果没有接收完整就需要重新发送,这样就可以保证数据的完整性。
  • ack:acknoledgement number 的缩写,表示确认号。接收端用它来给发送端反馈已经成功接收到的数据信息,它的值为希望接收的下一个数据包的起始序号,也就是 ack 的值所代表的序号前面的数据已经成功接收了
  • ACK:确认位,只有 ACK = 1 的时候 ack 才起作用。正常通信时 ACK 为 1,第一次发起请求因为没有需要确认接收的数据所以 ACK = 0。
  • SYN:同步位,用于建立连接时的同步序号。刚开始建立连接时并没有历史接收的数据,所以 ack 也没办法设置,这时按照正常的机制无法运行了,SYN 的作用就是来解决这样的问题,当接收端接收到 SYN = 1的报文的时候,就会直接将 ack 设置为接收到的 seq + 1 的值,注意这里的值并不是校验后设置的,而是根据 SYN 直接设置的,这时候正常的机制就可以运行了,所以 SYN 叫同步位。需要注意的是,SYN 会在前两次握手时为 1,这是因为通信双方的 ack 都需要设置一个初始值。
  • FIN:终止位,用来在数据传输完毕后释放连接。

纠错:上图中三次握手客户端第二次发送给服务端的 ack = y + 1

注:TCP 其实是一个很复杂的协议,具有很多种状态,状态之间的转换也是比较复杂的,这里不做详述。


上面是三次握手,下面是四次挥手(这里是客户端发送停止连接,也有可能是服务端发送,处理过程都一样)。

TCP 传输是全双工的,也就是说双方是对等的,可以同时传输数据,所以无论连接还是关闭都需要双方同时进行。

  • 三次握手
    • 前两次可以保证服务端可以正确接收并返回请求
    • 后两次可以保证客户端可以正确接收并返回请求
    • 在三次握手过程中还可以使用 SYN 标志初始化了双方的 ack 值。
  • 四次挥手
    • 双方分别发送 FIN 标志来关闭连接并让对方确认

三次握手和四次挥手保证了连接的可靠性,不过凡事有利有弊,这种模式也有它的缺点:

  • 首先是传输效率上会比较低
  • 另外三次握手中客户端需要发送两次数据才可以建立连接,这种特性可能会被一些别有用心的人利用
    • 比如,发送第一次握手(并接到第二次握手)后就不回应第三次握手了,这时服务端会以为是第二次握手的数据在传输过程中丢失了,然后重新发送第二次握手,默认情况下会一直发送五次,如果发送五次后还是收不到第三次握手,就会丢弃该请求,一两次就算了,如果出现大量这样的请求,会导致服务器浪费大量资源而无法处理正常请求。
    • 这就是 DDOS 攻击中的 SYN Flood 攻击,对于这种攻击一种应对方法是设置第二次请求的重发次数(tcp_synack_retries),不过重发次数太小也可以导致正常的请求因为网络原因而连接失败,具体设置多少合适,视具体情况而定。

传输层协议除了 TCP 外,还有 UDP,它们的主要区别是 TCP 是有连接的,UDP 是无连接的,TCP 协议会沟通好之后传输数据,而 UDP 协议是拿到目标地址后直接传输数据。

TCP UDP
连接 有连接 无连接
可靠性 可靠 不可靠
适合场景 邮件、网页等等 视频传输、语音输入等等

HTTP 协议底层传输默认使用的是可靠的 TCP 协议,但是 TCP 的特性也给 HTTP 带来了一些制约。可以搜索查看 HTTP1.0、HTTP2.0、HTTP3.0 相关信息。

HTTP 协议只是一套规则,并不能具体工作,就像是程序中的接口一样,而 Socket 是 TCP/IP 协议的一个具体的实现。

HTTP 协议

HTTP 协议是应用层协议,在 TCP/IP 协议接收到数据之后就需要 HTTP 协议来解析才可以使用。

HTTP 协议的报文结构非常重要。HTTP 中报文分为 请求报文(request message)响应报文(response message) 两种类型,这两种类型都包括三部分:行首、头部、主体

请求报文 响应报文
行首 请求行,包括方法(请求类型)、URL和 HTTP 版本三项内容 状态行,包括 HTTP 版本、状态码和简短原因三项内容,其中原因可有可无
头部 头部保存一些键值对的属性,用冒号分割 头部保存一些键值对的属性,用冒号分割
主体 主要保存 POST 类型的参数 页面要显示的结果

请求报文行首的请求类型:

  • GET、HEAD、POST、PUT、DELETE 等类型

响应报文行首的状态码(Response 的 status):

  • 分为五类:
    • 1XX:信息性状态码
    • 2XX:成功状态码
    • 3XX:重定向状态码
    • 4XX:客户端错误状态码
    • 5XX:服务端错误状态码

Servlet 与 Java Web 开发

Servlet 是 J2EE 标准的一部分,是 Java Web 开发的标准。标准比协议多了强制性的意义,不过它们的作用基本一样,都是用来制定统一的规矩。


通过前面的 TCP/IP 协议、HTTP 协议,我们可以得到具体的数据了,Servlet 的作用是对接收到的数据进行处理并生成要返回给客户端的结果。


Servlet 指定了 Java 中处理 Web 请求的标准,我们只需要按照标准规定的去做就可以了,但是不论是规范还是标准,它们都是不能干活的,要使用 Servlet 需要有对应的 Servlet 容器才行,比如,我们熟悉的 Tomcat 就是一个 Servlet 容器。

DNS 解析

DNS 服务器可以将域名解析成 IP 地址,但是 DNS 服务器是如何知道该域名和 IP 绑定的呢?

这需要域名的持有者自己将域名解析到对应的 IP 上,这样 DNS 服务器才可以查找到。


解析域名:

  • 记录类型:域名解析有多种解析的类型,如常用的 A 记录和 CNAME 记录。
    • A 记录是将域名解析到 IP(一个域名可以有多条 A 记录)
    • CNAME 记录是将域名解析到另一个域名(也就是作为一个域名的别名),查找时回返回目标域名的 IP
      • 比如 A 域名的 CNAME 记录 B 域名,当我们访问 A 域名时,DNS 解析结果回返回 B 域名的 IP
      • 这样做有三个好处:
        • 1、B 域名可能会有多条解析记录,而 A 域名通过 CNAME 记录就可以完成
        • 2、B 域名的 IP 发生变化,A 域名不需要修改解析内容就可以自动改变
        • 3、使用 CDN 时可以将用户直接访问的域名作为一个别名,然后将指向的域名通过 ns 记录指定 CDN 专用的 DNS 服务器进行解析,这样用户访问的域名解析使用的还是正常的 DNS 服务器,但是却可以获得 CDN 的 DNS 服务器解析的结果
  • 主机记录:就是域名前面的部分:如 www、bbs 等等,如果要解析顶级域名,也就是域名前面没有内容则使用 @ 代替
  • 解析现路:将不同的线路的用户解析到不同的服务器,比如将联通的用户解析到一个服务器,将电信的用户解析到一个服务器,这样就可以实现一种简单的 CDN
  • 记录值:解析的目标值,如 A 记录就是一个 IP,CNAME 记录就是对应的目标域名
  • TTL:本地 DNS 服务缓存解析结果的时间

Windows 本机域名和IP

Windows 电脑本机的 hosts 文件

设置的格式:IP + 空格 + 域名,一行一条记录(空格可以有多个)

如:

127.0.0.1 				localhost
127.0.0.1 				www.test.com
111.111.111.111 	www.111.com

第一行将 localhost 设置到本机,平时使用 localhost 就可以访问到本机。

第二行将 www.test.com 设置到本机

第三行将 www.111.com 设置到 111.111.111.111


本机在解析域名时会首先从 hosts 文件中查找,如果可以找到就直接使用,如果找不到才会从 DNS 服务器获取。

注:hosts 文件很重要,不要允许程序随意修改,它默认是只读的,需要权限才可以修改。


Author: NaiveKyo
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source NaiveKyo !
  TOC