网络是怎样连接的

avatarplhDigital nomad

前言

这可以作为一条学习前端知识的主线

输入url

这个步骤主要是解析url,

https:443//pipk.top/article?page=1&pageSize=15

url是uri的子集

上面url包括了以下信息。

  • http协议+ssl安全加密层
  • 443端口
  • pipk.top 服务器名字
  • /article服务器内部文件路径或者前台/后台路由
  • ?page=1&pageSize=15 在url中拼接的参数,当然你也可以在http主体中写入信息,毕竟url长度是有限制的,超过某个长度返回 状态码:414 Request-URI Too Large

dns解析

上面拿到服务器名字pipk.top就要去拿服务器名字对应的ip了,其中如果浏览器中没有dns缓存,去系统hosts文件拿对应ip映射,因为在window系统中,hosts文件级别较高,如果hosts文件还没有找到,那就看你有没有手动设置DNS服务器ip,如果没有,那就去离你最近的dns服务器拿映射ip了。 image

image

全世界DNS供应商大接力。

由于dns供应商会缓存ip映射,比如baidu这种,google这种,别人拿过了,就会缓存起来,如果理你最近的DNS有对应服务器缓存,那就直接拿到。 image

如果离你最近的DNS供应商没有dns缓存,那就要解析你的服务器名字了,比如:www.pipk.top,www是三级dns供应商名字,pipk是二级dns供应商名字。www是一级dns供应商的名字,而还有一个根级dns供应商,他就是 . ,他就只有13个子dns服务器,com,cn,top之类的个人都可以用的,还有org,这种政府机关专用服务器名字。

建立管道连接

拿到ip之后,就会去和服务器建立管道连接关系,客户端通过http协议传递信息给服务器,浏览器是无法建立连接的,只能委托系统建立连接,在http协议外层套一层tcp套接层,步骤分为以下4个步骤:

  • 创建套接字(创建套接字阶段)
  • 将管道连接到服务器的套接字上(连接阶段)
  • 收发数据(通讯阶段)
  • 断开管道并删除套接字(断开连接)

什么是连接

这就只是,客户端服务端双方都有保存对方的信息,这样就叫建立了连接,

关于TCP/UCP协议层

之前一直是TCP/IP,后来ip和TCP分开2层,通过命令行netstat -ano,在linux可查看所有TCP套接层的信息 image

关于获取dns -- 关于通过ip连接服务器

这是两个不同的步骤:

  • 去dns供应商拿url对应ip的过程:浏览器通过http协议发起委托,委托UDP模块(和TCP模块同一个层次,相比TCP功能更少,速度更快,适合去拿DNS),然后UDP委托IP模块,IP模块又去委托网卡驱动程,网卡驱动进而委托网卡向路由器发送请求,路由器将请求发给最近的dns供应商,层层委托,记住浏览器是没有发送网络请求的能力的,只有网卡有这个能力。直至拿到真实的url对应的ip地址

  • 上面步骤拿到真实ip后,又重复之前步骤,只不过这次是TCP协议层,层层包裹,建立http协议进而委托TCP模块创建套接层,然后又委托ip模块,进而委托网卡驱动,然后是网卡(一个网卡对应一个ip,如果多个网卡则由多个ip,以网卡为单位而不是计算机),当然一个get请求,通常不会太长,但是也有例外,比如大文件传输,比如博客论文800字这么长的发表,这些通过一个网络包是无法完成的,通常TCP协议包括HTTP报文,包括主体信息,不能超过1500字节。这个时候知道了,网络信息并不一定是一次一个包就能发送完成的,可能需要多个包,考虑因素当然是体积<1500字节,还有时间,等太久也不会管了。但是这两个是相互矛盾的,如果为了填满缓冲区一次发送一个包,就会造成延迟,如果时间优先,那么确实减少了网络延迟,却又极大的减小了网络资源传输效率,这是相互矛盾的。因此取中间值。

关于数据拆分于数据组装

由于ajax表单提交数据较大的话,通常需要在客户端将数据拆分成1460字节以下进行串联发送,同时给其添加ack编号以便于其不同包在服务端可以组装,这就涉及到ack编号的问题了,为了加大ack编号被破解的难度,通常ack初始值>1。当然ACK值的作用远不止如此,为什么这么说呢?因为数据以包(1460字节)为单位在客户端进行切割,再传输,到了服务端在根据包上面的ACK编号,对分割的包进行组装,这是一种重要的错误补偿机制。如果其中某个包丢失了呢?那就回去要求客户端再次发送这个包就好了,每个包分别对应了相对的ACK编号,进而根据编号进行组装。当然了,如果你要传1g的文件呢?这又涉及到一个重要的问题,缓存区(用于存储之前接受的包,进而进行组装的某个内存区域)。缓冲区域的空间是有限的。可能对于大文件,需要先存储部分内容,清空缓冲区,再进行传输吧。。。。

三次握手,这个属于建立TCL套接层的范畴

  • 第一次握手:建立连接。客户端发送连接请求报文段,将SYN位置为1,Sequence Number为x;然后,客户端进入SYN_SEND状态,等待服务器的确认;
  • 第二次握手:服务器收到SYN报文段。服务器收到客户端的SYN报文段,需要对这个SYN报文段进行确认,设置Acknowledgment Number为x+1(Sequence Number+1);同时,自己自己还要发送SYN请求信息,将SYN位置为1,Sequence Number为y;服务器端将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,此时服务器进入SYN_RECV状态;
  • 第三次握手:客户端收到服务器的SYN+ACK报文段。然后将Acknowledgment Number设置为y+1,向服务器发送ACK报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED状态,完成TCP三次握手。

完成了三次握手,客户端和服务器端就可以开始传送数据。以上就是TCP三次握手的总体介绍。 三次握手涉及到一个很重要的功能,如果我们丢失了某个包,怎么检测,其实利用ACK号,很容易查出来,并要求客户端重新发送这个包。这种错误补偿机制非常厉害。

四次分手

TCL套接层的4个步骤是,1.创建套接字(3次握手之后才能建立连接)。2.将管道套接在生成的套接字上面传输数据。3.传输数据。4.断开连接(4次分手后才能断开连接)。 4次分手(中断连接)可以由客户端或者服务端任意一方发起.。

传输层

接下来数据从路由器进入到了网络世界的传输再到下一个路由器,层层转发,其中的过程,非常复杂,有光纤传输,也有网线传输,电流是如何从高压线上传输的,网络数据同样参考这样的例子。网络通过路由器层层转发进行传输。 image

光纤和宽带传输对比

事实上光速和电场传播的速度相差无几吧(没学过物理),主要区别在于光纤损耗很小,而宽带损耗相对严重。所以光纤有优势。 而光纤是如何传递数据的,通常是数据(01010010101)转化为电信号高压/低压,电信号再转化为光信号,明/暗

防火墙

服务器不能裸奔吧,所以出现了防火墙,用于过滤掉其他软件发的数据,只留下特定程序同行,包括浏览器,app等。另外也可以像我一样租赁服务器,租腾讯云,阿里云,搬瓦工,vulrt等数据中心的服务器。用一句话来说就是:专业的事应该交给专业的人去做。防火墙的工作机制也就只能过滤不允许的程序包而已,并不能检查包的具体内容。无论加密与否。

多台服务器负载均衡

  • dns服务器轮询 假设给http://pipk.top域名设置dns解析为3个IP地址,优点自然是成本低,简单容易设置,弊端就是dns缓存非常严重,浏览器缓存一次,dns供应商缓存一次,清掉缓存不知道猴年马月的事情了,还有是操作的连续性,比如支付步骤分为3个小页面,跳到下一步就要进行新的轮询到另一台负载均衡的服务器么?

image

  • 负载均衡器

下面是百度的多台服务器负载均衡的情况。 image

缓存

代理服务器

  • 正向代理 正确地理解姿势,就是把他理解成防火墙就好了,你无权直接访问服务器,只能通过代理访问。

  • 反向代理 与正向代理相反,对于客户而言, 代理服务器就像是真正地服务器,用于保护和隐藏原始资源。

  • 透明代理 不懂。。。

路由器

电脑网卡转发数据包,就到路由器了,路由器提供的是转发功能,路由器中有一个ip协议表,通过这张表来查找下一个路由器, image

DOM渲染机制

  1. html文件生成dom树。 类似于BTS二叉树结构,父节点指向子节点,指针关系,先根据html构建基本数据结构,也就是dom tree的原型。

  2. javascript解析,css解析。 不分先后,看谁写在前面,他们之间的任务队列互斥,都是单线程的,他们的工作 就是为dom.tree添加属性,css最简单,它根据他自己的selector规则,往styles里面添加属性就好了。而js比较复杂,可能会操纵dom元素,即修改dom tree属性,又或者指针关系,再有js代码里面添加事件监听,即为某个domtree,然而浏览器貌似没有开发关于事件绑定的api,所以我们也无从查看事件绑定内部代码,同时一旦你点击页面,也就会触发click,他会在新的队列里面推送一条新任务,同理ajax,以及setTimeout,setInterval

3.repaint重绘

4.reflow重排

最后

突然发现这题目的标准答案应该围绕http协议DOM渲染机制这两个的完整版来说