TCP和UDP的区别
- TCP面向连接,UDP无连接
- TCP基于字节流,UDP基于报文
- TCP有流量控制和拥塞控制,UDP的吞吐量之取决于数据生成率、传输带宽
- TCP可靠按序交付,UDP尽可能最大交付且乱序
- TCP全双工点对点通信,UDP可以一对一,一对多,多对一,多对多
三次握手四次分手原因分析
TCP通过三次握手来建立连接,通过四次回收来端开连接
TCP三次握手的主要原因:
- 避免历史连接:
三次握手的首要原因是为了防止旧的重复连接初始化造成混乱。现在有一种情景,就的package 比带有最新序号的package优先到达了服务端。服务端就会恢复旧的包的序列号+1, 客户端通过ack就知道数据到达的顺序是由问题的,这是一个历史连接(序列号过期或者超时), 客户端就会发送RST报文给服务端,表示终止这一次连接。
如果是历史连接,则第三次握手发送的报文时RST报文,以此终止历史连接;
如果不是历史连接,则第三次发送的报文是 ACK 报文,通信双方就会成功建立连接; - 用于同步双方初始序列号:
发送初始序列号之后,需要对方发送ack来进行序列号的同步应答,以来一回才可以保证双方的序列号能被可靠的同步。4次握手可以简化为三次握手,因为 在服务器进行应答的同时可以发送初始化序列号进行同步。
两次握手只能保证一方的初始序列号能被对方成功接收,没有办法保证双方的初始学列号都能被确认接受。 - 避免资源浪费
如果只有「两次握手」,当客户端的 SYN 请求连接在网络中阻塞,客户端没有接收到 ACK 报文,就会重新发送 SYN ,由于没有第三次握手,服务器不清楚客户端是否收到了自己发送的建立连接的 ACK 确认信号,所以每收到一个 SYN 就只能先主动建立一个连接,这会造成什么情况呢?
如果客户端的 SYN 阻塞了,重复发送多次 SYN 报文,那么服务器在收到请求后就会建立多个冗余的无效链接,造成不必要的资源浪费
为什莫是3次握手:
- 3次握手时连接双方都确认自己和对方有手法能力的最少握手次数- 若只握手2次,服务器端在接受到客户点的请求就打开连接, 可能受到网络中的失败请求而误打开连接,造成资源浪费;- 若3第三次握手失败,服务器会关闭连接,防止SYN DDOS攻击
为什莫是4次挥手:
当服务器收到客户端的关闭请求时,先相应ACK信号表示自己收到了客户端的请求,再将自己需要发给客户端的数据发完,最后再发送FIN信号表示自己的数据传输完毕。ACK和FIN 分开相应使得挥手比握手多了一次。
不使用【两次握手】和【四次握手】
- 【两次握手】:无法防止历史连接的建立,会造成双方自愿的浪费,页无法可靠的同步双方序列号;
- 【四次握手】:三次握手就已经理论上最少可靠连接建立,所以不需要使用更多的通信次数。
为什莫客户端要等待2MSL再关闭连接:
- 为了防止客户端的最后一个ACK没有到达服务器, 使得服务器端一直未关闭连接,此时客户端还能重新发送ACK给服务器, 并且重启2MSL计时器;MSL(Maximum Segment Lifetime)报文最大生存时间,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。Linux系统中,2MSL默认时长为60秒
- 为了让这次连接中的所有消息都消失在网络中,防止新的连接收到旧的失效请求(会触发TCP的拥塞控制,流量控制机制, 影响效率)
为什莫需要TIME-WAIT状态:
- 防止具有相同「四元组」的「旧」数据包被收到;
- 保证「被动关闭连接」的一方能被正确的关闭,即保证最后的 ACK 能让被动关闭方接收,从而帮助其正常关闭;
从输入URL回车之后都发生了什么
从输入URL到页面展示分为一下步骤
- 输入域名
- 根据域名让DNS取解析查询其IP
- 通过IP地址鱼服务器建立TCP连接
- 客户端向服务端发送HTTP请求,如果服务器返回301重定向, 浏览器根据response 中header 的location再次发送请求
- 服务器接收到请求并相应HTTP请求, 处理请求生成html代码。返回给浏览器
- 浏览器开始解析渲染页面并显示
- 关闭连接
输入地址
在浏览器中输入网址的时候,浏览器会从本地浏览器换从中查询你输入的内容,如果有缓存过就直接将页面返回给你。
DNS
DNS(Domain Name System)服务是应用层的协议。他是一个域名和IP向映射的一个表。你的主机会拿着申请访问的域名去查询每一张表。从本地ISP DNS开始,没有就递归查找询问DNS跟服务器。找到了就会返回给客户端IP地址。
DNS就是让你去获取资源所在IP地址,当大量的用户同一时间去查询的时候就需要DNS负载均衡,它负责合理安排资源的分配根据用户请求的所在地。CDN(Content Delivery Network)
TCP连接
建立TCP连接
掠过…
发送HTTP请求 和 接受HTTP response
将reponse中的信息进行缓存, 包括了Cookie, Cache-Expire, LastModify 等服务端想要提供的信息
略过。。。。。。
渲染页面
在浏览器没有完整接受全部 HTML 文档时,它就已经开始显示这个页面了,不同浏览器可能解析的过程不太一样,这里我们只介绍 WebKit 的渲染过程。
- 解析HTML,构建 DOM 树
- 解析 CSS ,生成 CSS 规则树
- 合并 DOM 树和 CSS 规则,生成 render 树
- 布局 render 树( Layout / reflow ),负责各元素尺寸、位置的计算
- 绘制 render 树( paint ),绘制页面像素信息
- 浏览器会将各层的信息发送给 GPU,GPU 会将各层合成( composite ),显示在屏幕上
需要注意的是,这是一个渐进的过程,呈现引擎为了力求显示的及时,会在文档请求不完全的情况下就开始渲染页面,同时,如果在解析的过程中遇到script的时候,文档的解析将会停止下来,立即解析执行脚本,如果脚本是外部的,则会等待请求完成并解析执行。所以,为了不阻塞页面地呈现,一般会把script脚本放在文档的最后。
关闭TCP连接, 4次挥手
现在的页面为了优化请求的耗时,默认都会开启持久连接(keep-alive),那么一个TCP连接确切关闭的时机,是这个tab标签页关闭的时候。这个关闭的过程就是著名的四次挥手。关闭是一个全双工的过程,发包的顺序的不一定的。一般来说是客户端主动发起的关闭,过程如下。
假如最后一次客户端发出的数据seq = x, ack = y;
- 客户端发送一个FIN置为1的包,ack = y, seq = x + 1,此时客户端的状态为 FIN_WAIT_1
- 服务端收到包后,状态切换为CLOSE_WAIT发送一个ACK为1的包, ack = x + 2。客户端收到包之后状态切换为FNI_WAIT_2
- 服务端处理完任务后,向客户端发送一个 FIN包,seq = y; 同时将自己的状态置为LAST_ACK
- 客户端收到包后状态切换为TIME_WAIT,并向服务端发送ACK包,ack = y + 1,等待2MSL后关闭连接。为什么客户端等待2MSLMSL: 全程Maximum Segment Lifetime,中文可以翻译为报文最大生存时间。等待是为了保证连接的可靠性,确保服务端收到ACK包,如果服务端没有收到这个ACK包,将会重发FIN包给客户端,而这个时间刚好是服务端等待超时重发的时间 + FIN的传输时间。
在上层应用准备发送数据的时候,操作系统内核发生的事情
在这个过程中起着重要作用的是TCB模块。 当应用希望些数据的时候,先将数据放入到一个传冲去,然后根据算法flush之后发送到网卡中。网卡收到数据时, 数据包要先经过如下几步:
- 数据包先经过网卡校验正确
- 数据链路层根据报文头的类型给不同的上层类型(IP 或者其他), 并且一处数据链路层的报文头
- IP层也先进行校验, 然后根据IP报文头选择不同的类型(TCP或者UDP), 然后移除IP报文头, 将剩余的数据发送到相应的处理程序(tcp或者udp)
- 到了TCP层,处理程序此时根据TCP首部中的端口号选择socket, 并且将缓存区的数据拷贝进去
每个socket都有TCB(发送缓冲区,接受缓冲区,和其他控制或者表示结构)。网卡传输数据流, 当交给应用层上层的时候会改变数据结构。 Socket连接使用TCP连接, 四元组就是一对连接的唯一标识(源IP, 目的IP, 源port, 目的port)。
当网卡收到数据之后,首先经过校验没有错误之后,通过DMA直接发送到内存缓冲区中,然后给CPU发送一个中断信号,通知操作系统一个数据包到了。在操作系统获悉到一个数据包来到之后,就利用中断函数来一步步执行并解析数据包,知道TCP层,到了TCP层,TCP要决定将数据包发给那个socket的接收缓冲区。
怎么找?这里TCP就是利用连接四元组,并以这个四元组为key,查找hash表找到对应的socket的socket结构指针,并利用该指针找到对应socket的接收缓冲区,并将载荷数据拷贝进去