朋友们好啊,我是来亦何哀,刚才有朋友问我,发生什么事了,给我发来几张截图,我一看,哦,原来是昨天,有两个年轻人,一个秃顶,一个半秃顶,他们说,我在题海里,头发刷没了,你能不能帮助治疗一下,很快,就给我发来几道题,我一看,我一个都不会做,看来搞不了窝里斗了,我还是学习一些前端应该了解的计算机网络知识吧。

DNS

DNSDomain Name System,域名系统),就是平时我们说的域名,当我们输入home.cnblogs.com访问网站。实际上是访问了不同的域。其中”.”是DNS命称空间,用来分割不同域,home(三级域)和cnblogs(二级域)和com(顶级域),所以其实www.cnblogs.comcnblogs.com`是两个不同的域名。

如何根据域名查询到IP

  1. 访问客户端的DNS缓存:浏览器缓存 -> 系统缓存(host) -> 路由器缓存,所以通过修改系统hosts文件我们可以把域名改成本地的地址,进行调试开发,对于经常访问的网站,也可以直接设置到hosts里,加快访问速度。
  2. 访问ISP DNS服务器(ISP,互联网服务提供商,有联通电信移动等。如果你是电信网络,则进入电信的DNS缓存服务器,以下简称本地),如果本地服务器有,则直接返回;如果没有,让本地DNS服务器去逐个咨询查找。
  3. 本地去咨询DNS根服务器,DNS根服务器发现是.com区域管理的,告诉本地去咨询它。
  4. 本地去咨询.com顶级域服务器,.com域服务器告诉本地去咨询cnblogs.com主区域的服务器。
  5. 本地去咨询baidu.com主域名服务器,baidu.com域服务器查找到对应的IP地址,返回给本地。
  6. 本地DNS云服务器通知用户对方IP地址,同时缓存这个IP地址,下次就直接访问了。

DNS有关网络的性能优化

  • 使用DNS预解析,可以通过用meta信息来告知浏览器, 我这页面要做DNS预解析
<meta http-equiv="x-dns-prefetch-control" content="on" />
  • 可以使用link标签来强制对DNS做预解析
<link rel="dns-prefetch" href="xxx" />

DUP连接

用户数据包协议(User Datagram Protocol),简称UDP,是基于IP之上开发能和应用打交道的协议,通过IP地址信息把数据包发送给指定的电脑,
每个想访问网络的程序都需要绑定一个端口号,UDP再通过端口号把数据包分发给正确的程序。

UDP传输的缺陷:

  • 数据包在传输过程容易丢失
  • 大文件传输中,UDP并不知道如何组成这些数据包,不知道如何还原成完整的文件。虽然UDP不能保证数据可靠性,但是传输速度非常快,所以UDP会应用在一些关注速度、但不那么严格要求数据完整性的领域,如在线视频、互动游戏等。

TCP连接

TCPTransmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。在一个TCP连接中,会有3个过程:

建立连接阶段

这个阶段是通过 “三次握手” 来建立客户端和服务器之间的连接。
TCP提供面向连接的通讯传输。面向连接是指数据通讯开始先做好两端之间的准备工作。
所谓三次握手,是指在建立一个TCP连接时,客户端和服务器总共要发送3个数据包来确认连接的建立。

三次握手主要作用是:

  • 确认双方的接收能力和发送能力
  • 指定自己的初始化序列号,为后面的可靠性做准备

三次握手的过程是:

刚开始客户端处于Closed的状态,服务器处于Listen状态。服务器说你没用,客户端说我有用,然后说要试试。

SYN(synchronous 建立联机)、seq(Sequence number 顺序号码)、小写ack(acknowledgement 确认)、大写ACK(Acknowledgement 标识位,可以通过它标识包的性质, [ACK] or [SYN] or [FIN] )

  1. 客户端发送到服务器,客户端上来就是一个发送SYN报文给服务器,并且指明客户端初始化序列号为ISN(c),即以SYN=1,seq=x的形式发送过去。此时客户端处于SYN_SEND状态。
  2. 服务器发送给客户端,服务器全部防住了,怎么防住的呢?自然是采用经典的接、化、发,接手收到客户端的SYNISN(c),化手设置ACK = ISN(c) + 1以及指明服务器初始化序列号为ISN(s),然后以SYN=1, ACK=x+1, seq=y的形式发送给客户端。
  3. 客户端发送到服务器,防出去以后,自然是传统比试,以点到为止,但是客户端不讲武德,设置ACK = ISN(s) + 1,将自身的ISN(c) + 1,以ACK=y+1, seq=x+1的形式发送给服务器,这就坏了,两人结仇了,此时客户端处于ESTABLISHED阶段,服务器收到报文,也处于ESTABLISHED阶段。

记忆规律:

建立连接 => 建立连接与确认 => 再次确认

  1. 首先发一个建立连接SYN=1和一个顺序号码seq=x。
  2. 被服务器接住了,也发送建立连接SYN=1,同时发送确认将客户端顺序号码+1返回ACK=x+1,再带上自己的服务端顺序号码seq=y。
  3. 客户端再发送确认将服务端顺序号码+1返回ACK=y+1,再将客户端顺序号码也+1返回seq=x+1。
    image.png
    问题:两次握手不行吗?

三次握手的目的:

  1. 客户端发送数据给服务器,服务器确认自己可以接受客户端的请求。
  2. 服务器发送数据给客户端,客户端确认自己可以发送数据给服务器,也可以接受到服务器的请求。
  3. 客户端发送数据给服务器,服务器确认自己可以发送数据给客户端。

如果采用两次握手,客户端发送数据给服务器,服务器确认后就当连接开始,就很可能遇到下面这种情况:

  1. 客户端发送一次请求给服务器……指定时间后没响应再发了一个。
  2. 服务器先接收到后一个建立连接的请求,然后前一个建立连接的请求,因为网络延迟等问题,在第二个之后达到了。
  3. 服务器认为第二个请求是最新发的,于是向客户端发送确认报文段,同意建立连接,于是连接建立了(两次握手)。
  4. 这时候客户端还在等待最新的请求连接(第二次请求),自动忽略服务器发送的关于第一个请求连接的响应,也不发送数据。
  5. 服务器一直等待客户端发送数据,服务器资源被占用。

问题:三次握手过程中可以携带数据吗?

答案:第三次握手的时候可以携带,第一第二次不可以携带。
原因:如果第一次可以携带数据的话,有可能是恶意攻击服务器。这时候释放大量的数据,不理会服务器的的承受能力,让服务器花费很多时间、内存空间接收报文。
第三次握手的时候,客户端处于ESTABLISHED状态了,它可以建立连接并且知道服务器的接收、发送能力是正常的,所以可以携带数据了。

传输数据阶段

此时客户端和服务器都处于ESTABLISHED状态。
这个阶段中,接收端需要对每个数据包进行确认操作。即接收端在接收到数据包之后,需要发送确认数据包给发送端。
如果发送端在规定时间内没有接收到接收端的反馈确认消息,那么判断丢包(数据包丢失),从而触发自身的重发机制。
一个大的文件在传输过程中会被拆分为多个小的数据包,接收端按照TCP头中的序号进行排序,保证组成完整的数据。

断开连接阶段

数据传输完毕之后,需要终止连接,通过四次挥手来保证双方都能断开连接。
由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。
这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。
首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。

四次挥手的过程是:

FIN( finish 结束 )

  1. 客户端发送给服务器,客户端以FIN=1, seq=u的形式发送给服务器,表示需要关闭客户端和服务器的数据传输。此时客户端处于FIN_WAIT状态。
  2. 服务器发送给客户端,服务器收到信息,先返回ACK给客户端,即以ACK=1, seq=v, ack=u+1的形式返回给客户端,表示收到客户端报文了。此时服务器处于CLOST_WAIT状态。
  3. 服务器发送给客户端,服务器等待一会,看客户端还有没有数据没发过来,等处理完这些数据之后,也想断开连接了,于是发送FIN给客户端,即以FIN=1, ACK=1, seq=w, ack=u+1的形式发送给客户端。此时服务器处于LAST_ACK状态。
  4. 客户端发送给服务器,客户端收到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
image.png
问题:为什么需要四次挥手?

因为服务器接收到客户端的关闭请求之后。

  1. 可能有一些数据因为网络延迟等问题没有发送到,直接关闭会导致这些数据没有接收到;
  2. 可能服务器也有一些数据要发送给客户端,要确保这些数据发送完。

TCP和UDP的区别

  • TCP是面向连接的。UDP是无连接的,即发送数据前不需要先建立链接。
  • TCP提供可靠的服务,也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达,因此适合大数据量的交换。UDP尽最大努力交付,即不保证可靠交付,因此UDP是不可靠的
  • TCP是面向字节流。UDP面向报文,并且网络出现拥塞不会使得发送速率降低(因此会出现丢包,对实时的应用比如IP电话和视频会议等)。
  • TCP只能是1对1的。UDP支持1对1,1对多。
  • TCP的首部较大为20字节。而UDP只有 8 字节。

Q.E.D.


学而不厌 不耻下问