前端应该了解的计算机网络知识(一)
朋友们好啊,我是来亦何哀,刚才有朋友问我,发生什么事了,给我发来几张截图,我一看,哦,原来是昨天,有两个年轻人,一个秃顶,一个半秃顶,他们说,我在题海里,头发刷没了,你能不能帮助治疗一下,很快,就给我发来几道题,我一看,我一个都不会做,看来搞不了窝里斗了,我还是学习一些前端应该了解的计算机网络知识吧。
DNS
DNS
(Domain Name System
,域名系统),就是平时我们说的域名,当我们输入home.cnblogs.com
访问网站。实际上是访问了不同的域。其中”.”是DNS
命称空间,用来分割不同域,home
(三级域)和cnblogs
(二级域)和com
(顶级域),
所以其实www.cnblogs.com
和cnblogs.com
是两个不同的域名。
如何根据域名查询到ip
?
- 访问客户端的
DNS
缓存:浏览器缓存 -> 系统缓存(host
) -> 路由器缓存,所以通过修改系统hosts
文件我们可以把域名改成本地的地址,进行调试开发,对于经常访问的网站,也可以直接设置到hosts
里,加快访问速度。 - 访问
ISP DNS
服务器(ISP
,互联网服务提供商,有联通电信移动等。如果你是电信网络,则进入电信的DNS
缓存服务器,以下简称本地),如果本地服务器有,则直接返回;如果没有,让本地DNS
服务器去逐个咨询查找。 - 本地去咨询
DNS
根服务器,DNS
根服务器发现是.com
区域管理的,告诉本地去咨询它。 - 本地去咨询
.com
顶级域服务器,.com
域服务器告诉本地去咨询cnblogs.com
主区域的服务器。 - 本地去咨询
baidu.com
主域名服务器,baidu.com
域服务器查找到对应的IP
地址,返回给本地。 - 本地
DNS
云服务器通知用户对方IP
地址,同时缓存这个IP
地址,下次就直接访问了。
DNS
有关的网络性能优化
- 使用
DNS
预解析,可以通过用meta
信息来告知浏览器, 我这页面要做DNS预解析
<meta http-equiv="x-dns-prefetch-control" content="on" />
- 可以使用
link
标签来强制对DNS
做预解析
<link rel="dns-prefetch" href="xxx" />
UDP
连接
用户数据包协议(User Datagram Protocol
),简称UDP
,是基于IP
之上开发能和应用打交道的协议,通过IP
地址信息把数据包发送给指定的电脑,
每个想访问网络的程序都需要绑定一个端口号,UDP
再通过端口号把数据包分发给正确的程序。
UDP
传输的缺陷:
- 数据包在传输过程容易丢失
- 大文件传输中,
UDP
并不知道如何组成这些数据包,不知道如何还原成完整的文件。
虽然UDP
不能保证数据可靠性,但是传输速度非常快,所以UDP
会应用在一些关注速度、但不那么严格要求数据完整性的领域,如在线视频、互动游戏等。
TCP
连接
TCP
(Transmission Control Protocol
,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。在一个TCP
连接中,会有3个过程:
建立连接阶段
这个阶段是通过 “三次握手” 来建立客户端和服务器之间的连接。
TCP
提供面向连接的通讯传输。面向连接是指数据通讯开始先做好两端之间的准备工作。
所谓三次握手,是指在建立一个TCP
连接时,客户端和服务器总共要发送3个数据包来确认连接的建立。
三次握手主要作用是:
- 确认双方的接收能力和发送能力
- 指定自己的初始化序列号,为后面的可靠性做准备
三次握手的过程是:
刚开始客户端处于Closed
的状态,服务器处于Listen
状态。服务器说你没用,客户端说我有用,然后说要试试。
SYN
(synchronous
建立联机)、seq
(Sequence number
顺序号码)、小写ack
(acknowledgement
确认)、大写ACK
(Acknowledgement
标识位,可以通过它标识包的性质, [ACK
] or [SYN
] or [FIN
] )
- 客户端发送到服务器,客户端上来就是一个发送
SYN
报文给服务器,并且指明客户端初始化序列号为ISN(c)
,即以SYN=1, seq=x
的形式发送过去。此时客户端处于SYN_SEND
状态。 - 服务器发送给客户端,服务器全部防住了,怎么防住的呢?自然是采用经典的接、化、发,接手收到客户端的
SYN
和ISN(c)
,化手设置ACK = ISN(c) + 1
以及指明服务器初始化序列号为ISN(s)
,然后以SYN=1, ACK=x+1, seq=y
的形式发送给客户端。 - 客户端发送到服务器,防出去以后,自然是传统比试,以点到为止,但是客户端不讲武德,设置
ACK = ISN(s) + 1
,将自身的ISN(c) + 1
,以ACK=y+1, seq=x+1
的形式发送给服务器,这就坏了,两人结仇了,此时客户端处于ESTABLISHED
阶段,服务器收到报文,也处于ESTABLISHED
阶段。
记忆规律:
建立连接 => 建立连接与确认 => 再次确认
- 首先发一个建立连接
SYN=1
和一个顺序号码seq=x
。 - 被服务器接住了,也发送建立连接
SYN=1
,同时发送确认将客户端顺序号码+1返回ACK=x+1
,再带上自己的服务端顺序号码seq=y
。 - 客户端再发送确认将服务端顺序号码+1返回
ACK=y+1
,再将客户端顺序号码也+1返回seq=x+1
。
问题:两次握手不行吗?
三次握手的目的:
- 客户端发送数据给服务器,服务器确认自己可以接受客户端的请求。
- 服务器发送数据给客户端,客户端确认自己可以发送数据给服务器,也可以接受到服务器的请求。
- 客户端发送数据给服务器,服务器确认自己可以发送数据给客户端。
如果采用两次握手,客户端发送数据给服务器,服务器确认后就当连接开始,就很可能遇到下面这种情况:
- 客户端发送一次请求给服务器……指定时间后没响应再发了一个。
- 服务器先接收到后一个建立连接的请求,然后前一个建立连接的请求,因为网络延迟等问题,在第二个之后达到了。
- 服务器认为第二个请求是最新发的,于是向客户端发送确认报文段,同意建立连接,于是连接建立了(两次握手)。
- 这时候客户端还在等待最新的请求连接(第二次请求),自动忽略服务器发送的关于第一个请求连接的响应,也不发送数据。
- 服务器一直等待客户端发送数据,服务器资源被占用。
问题:三次握手过程中可以携带数据吗?
答案:第三次握手的时候可以携带,第一第二次不可以携带。
原因:如果第一次可以携带数据的话,有可能是恶意攻击服务器。这时候释放大量的数据,不理会服务器的的承受能力,让服务器花费很多时间、内存空间接收报文。
第三次握手的时候,客户端处于ESTABLISHED
状态了,它可以建立连接并且知道服务器的接收、发送能力是正常的,所以可以携带数据了。
传输数据阶段
此时客户端和服务器都处于ESTABLISHED
状态。
这个阶段中,接收端需要对每个数据包进行确认操作。即接收端在接收到数据包之后,需要发送确认数据包给发送端。
如果发送端在规定时间内没有接收到接收端的反馈确认消息,那么判断丢包(数据包丢失),从而触发自身的重发机制。
一个大的文件在传输过程中会被拆分为多个小的数据包,接收端按照TCP
头中的序号进行排序,保证组成完整的数据。
断开连接阶段
数据传输完毕之后,需要终止连接,通过四次挥手来保证双方都能断开连接。
由于TCP
连接是全双工的,因此每个方向都必须单独进行关闭。
这个原则是当一方完成它的数据发送任务后就能发送一个FIN
来终止这个方向的连接。收到一个FIN
只意味着这一方向上没有数据流动,一个TCP
连接在收到一个FIN
后仍能发送数据。
首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
四次挥手的过程是:
FIN
( finish
结束 )
- 客户端发送给服务器,客户端以
FIN=1, seq=u
的形式发送给服务器,表示需要关闭客户端和服务器的数据传输。此时客户端处于FIN_WAIT
状态。 - 服务器发送给客户端,服务器收到信息,先返回
ACK
给客户端,即以ACK=1, seq=v, ack=u+1
的形式返回给客户端,表示收到客户端报文了。此时服务器处于CLOST_WAIT
状态。 - 服务器发送给客户端,服务器等待一会,看客户端还有没有数据没发过来,等处理完这些数据之后,也想断开连接了,于是发送
FIN
给客户端,即以FIN=1, ACK=1, seq=w, ack=u+1
的形式发送给客户端。此时服务器处于LAST_ACK
状态。 - 客户端发送给服务器,客户端收到
FIN
之后,返回ACK
报文作为应答,即以ACK=1, ack=w+1, seq=u+1
的形式发送给服务器。此时客户端处于TIME_WAIT
状态。
过一阵子之后,客户端确保服务器收到自己的ACK
报文了,则变成CLOSED
状态。服务器接受到ACK
报文之后,就也处于CLOSED
状态了。
记忆规律:
客户端告知结束 => 服务器确认 => 服务器告知结束 => 客户端确认
FIN=1, seq=u
=> ACK=1, ack=u+1, seq=v
=> FIN=1, seq=w, ACK=1, ack=u+1
=> ACK=1, seq=u+1, ack=w+1
问题:为什么需要四次挥手?
因为服务器接收到客户端的关闭请求之后。
- 可能有一些数据因为网络延迟等问题没有发送到,直接关闭会导致这些数据没有接收到;
- 可能服务器也有一些数据要发送给客户端,要确保这些数据发送完。
TCP
和UDP
的区别
TCP
是面向连接的。UDP
是无连接的,即发送数据前不需要先建立链接。TCP
提供可靠的服务,也就是说,通过TCP
连接传送的数据,无差错,不丢失,不重复,且按序到达,因此适合大数据量的交换。UDP
尽最大努力交付,即不保证可靠交付,因此UDP
是不可靠的TCP
是面向字节流。UDP
面向报文,并且网络出现拥塞不会使得发送速率降低(因此会出现丢包,对实时的应用比如IP
电话和视频会议等)。TCP
只能是1对1的。UDP
支持1对1,1对多。TCP
的首部较大为20字节。而UDP
只有 8 字节。