笔者从事后端技术十余年,期间也面试别人,也有被别人面试,今天特意将这些面试的知识点总结下,希望能够在工作或者面试中帮助到大家。
说说OSI模型和TCP/IP模型
OSI(Open System Interconnection,开放式通信互联) 是由 ISO(International Organization for Standardization,国际标准化组织) 制定的标准模型。旨在将世界各地的各种计算机互联。然而,OSI 模型过于庞大、复杂。参照此模型,技术人员开发了 TCP/IP 协议栈,简化 OSI 七层模型为 TCP/IP 四层模型。获得了更广泛的使用。
OSI 模型和 TCP/IP 模型对比:
什么是TCP
TCP(Transmission Control Protocol 传输控制协议)是一种面向连接(连接导向)的、可靠的、 基于IP的传输层协议。
TCP是如何保证数据可靠的
- 通过数据流的方式传输,将数据截成合理的长度;
- 对每段报文进行编号,保证数据流的顺序;
- 收到数据进行重排序,并且丢弃重复数据;
- 收到报文后,给出确认响应;
- 超时重发;
- 校验和;
- 流量控制(针对本程序的接受能力)和拥塞控制(针对整个网络)。
说说TCP和UDP的区别
协议差别
功能 | TCP | UDP |
是否连接 | 面向连接 | 无连接 |
传输可靠性 | 可靠 | 不可靠 |
应用场合 | 传输少量数据 | 传输大量数据 |
速度 | 慢 | 快 |
区别总结:
- TCP 的面向连接的,在发送数据之前要建立连接;UDP 是无连接的,即发送数据之前不需要建立连接;
- TCP 提供可靠的服务,通过 TCP 连接传送的数据,不丢失,不重复,且按序到达。UDP 尽最大努力交付,不保证可靠交付;
- TCP 面向字节流,把数据看成一连串无结构的字节流;UDP 是面向报文的,对应用程序的报文既不拆分也不合并;
- TCP 有流量控制和拥塞控制,UDP 没有拥塞控制;
- TCP 连接只能是点到点的,UDP 支持一对一,一对多,多对一和多对多的交互通信;
- TCP首部至少开销 20 字节,UDP 的首部结构简单,开销小,只有8个字节;
- 由于 TCP 要维护连接和保证可靠性,所以对系统资源的要求较多, UDP 相对要小得多。
TCP建立连接的过程
TCP建立连接发生在client端调用connect系统调用的时候。其目的是为了对每次发送的数据量进行跟踪与协商(即交换双方窗口大小),确保数据段的发送和接收同步,根据所接收到的数据量而确认数据发送、接收完毕后何时撤消联系,并建立虚连接。
TCP建立连接的过程,是一个三次握手的过程。
- 第一次握手:client端向server发送连接请求,SYN=1(SYN表示发送端与接收端要建立连接),seq = x。此时client端进入SYN_SENT阶段
- 第二次握手:server在收到client端的请求后,向client回复SYN = 1(SYN表示发送端与接收端要建立连接) 和 ACK = 1(表示对发送端请求进行应答),seq = y, ack = x + 1。此时server端进入SYN_RCVD阶段
- 第三次握手:client端收到server端的请求和响应之后,同样需要向server端回复消息。向server端发送ACK = 1(表示对server端的响应),seq = x + 1,ack = y + 1.此时客户端进入ESTABLISH阶段。server端在收到该ACK后,也进入ESTABLISH阶段。
通俗理解:
- A 想要和 B 通信,首先跟 B 说:“我想和你通信”;
- B 收到这条信息之后,回复 A 说:“收到。我也想和你通信”;
- A 收到之后就知道,原来 B 也想通信,回复 B 说:“收到”。
上述三次握手过程,我们用图表示为。
为什么建立连接是3次,而不是2次或者4次
按理说,在客户端收到服务器发过来的确认报文后(第二次握手后),通信双方就可以确定对方的请求建立连接的意图了,那为什么客户端还要再发送一次 ACK 报文呢?
主要是防止已经失效的连接请求报文又到达服务器端这种情况。
“已经失效的连接请求报文”是这样产生的:当网络环境差的时候,客户端发送的连接请求报文可能丢失,也有可能滞留在某个节点。当客户端等待一定时间后,没有收到服务器发送的确认报文,就认为之前发送的连接请求报文失效了。客户端会再次发送连接请求报文。
但是如果滞留在某个节点的报文经过长时间延迟后到达了服务器端,服务器并不知道这是一个失效的报文,它以为是客户端的正常连接请求,就会返回确认报文,同意连接建立。
如果采用2次握手的方法,这时新的连接已经建立了。但是实际上,客户端并没有发起请求,它不会对服务端的确认报文做出反应,更不会发送数据给服务端。而服务端却以为新的连接已经建立,一直在等待客户端发送数据,这样就造成了资源的浪费。
而如果采用4次握手的情况,就是将第二次SYN和ACK分成两步来操作,这样会浪费资源以及性能浪费。
采用3次握手就可以避免这样情况。上述的情形下,服务器没有收到客户端对自己发送过去的确认报文的 ACK 报文,就知道客户端没有请求建立连接。
TCP断开连接的过程
当client端和server端的数据传输完成之后,就需要断开连接,以节省资源。断开连接的过程,我们一般称之为四次挥手(与建立连接的三次握手相对应)。
- 第一次挥手:client端向server端发送断开连接的请求,告诉server端,我这边不再需要跟你传输数据。发送FIN=1(表示发送断开连接请求),seq=x,此时client端处于FIN_WAIT_1阶段
- 第二次挥手:server端在收到client端的断开请求后,需要告诉客户端已经收到请求。因此向client端回复ACK=1,seq=y,ack=x+1(表示对client发送的seq=x进行确认)。此时client端处于FIN_WAIT_2阶段,server端处于CLOSE_WAIT阶段。
- 第三次挥手:当server端不再需要与client端传输数据,就向client端发送断开连接的请求。FIN=1(表示发送断开连接请求),ACK=1(表示对client端的上一次断开连接应答)。seq=z,ack=x+1(上一次断开连接请求时候seq=x)。此时server端处于LAST_ACK阶段。
- 第四次挥手:client端收到server端断开连接的请求后,需作出应答,因此ACK=1.seq=x+1,ack=w+1(表示对上一次请求的应答)
通俗理解:
- A 没有数据发送,就和 B 说:“我没有数据给你了,但是如果你还有数据没发送完,则不必急着断开,还可以继续发送数据”;
- B 收到后,会告诉 A说:“收到。”,然后继续发送数据给 A;
- 当 B 端确定数据已发送完成,则告诉 A:“好了,我这边数据发完了,准备好关闭连接了”;
- A 听到后,和 B 说:“好的,你断开吧。”,然后在等待 2MSL 时间后断开。
至此,断开连接的过程讲解完毕,用图的方式如下:
为什么client要等待 2MSL 后才断开连接?
网络的状态是不确定的,最后 Client 发送的确认报文可能丢失。如果确认报文丢失并且 Client 不等待,直接断开连接。此时 Server 端在发送 FIN 报文后,不会收到任何响应。等待一段时间后,会重发 FIN 报文,但此时 Client 端已经关闭。Server 就会一直重发 FIN 报文。而如果 Client 端处于等待状态时,就会回复确认报文给 Server,让 Server 关闭。同时,在 2MSL 内没有收到 FIN 报文,说明 Server 端收到了确认报文,已经关闭,这样自己也可以关闭了。2MSL 是从 Client 到 Server 时间的2倍,也就是发送确认报文和接受 FIN 报文的时间。
为什么TCP断开连接是4次
因为TCP是全双工,在一端断开连接之后,另外一端在需要的时候,也需要断开连接。每一端的断开需要两次,即FIN和ACK,所以整个过程就是四次。
TCP是怎样进行流量控制
TCP必需要解决的可靠传输以及包乱序的问题,所以,TCP必需要知道网络实际的数据处理带宽或是数据处理速度,这样才不会引起网络拥塞,导致丢包。这就引入了滑动窗口和拥塞窗口。
在发送端通过拥塞窗口,在接收端通过滑动窗口。
滑动窗口协议是传输层进行流控的一种措施,接收方通过通告发送方自己的可以接受缓冲区大小(这个字段越大说明网络吞吐量越高),从而控制发送方的发送速度,不过如果接收端的缓冲区一旦面临数据溢出,窗口大小值也会随之被设置一个更小的值通知给发送端,从而控制数据发送量(发送端会根据接收端指示,进行流量控制)。
防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载。拥塞控制所要做的都有一个前提:网络能够承受现有的网络负荷。拥塞控制是一个全局性的过程,涉及到所有的主机、路由器,以及与降低网络传输性能有关的所有因素。
在浏览器中输入一个url后,浏览器的行为
浏览器本身是一个客户端,当你输入URL的时候,首先浏览器会去请求DNS服务器,通过DNS获取相应的域名对应的IP,然后通过IP地址找到IP对应的服务器后,要求建立TCP连接,等浏览器发送完HTTP Request(请求)包后,服务器接收到请求包之后才开始处理请求包,如果请求的资源包含有动态语言的内容,那么服务器会调用动态语言的解释引擎负责处理“动态内容”,并将处理得到的数据装在HTTP Response(响应)包返回给客户端;客户端收到来自服务器的响应后开始渲染这个Response包里的主体(body),等收到全部的内容随后断开与该服务器之间的TCP连接。
END
关于我:某互联网公司高级技术专家,长期从事后端研发工作,负责推荐引擎、广告引擎等业务。
关注公众号[高性能架构探索],后台回复资料,免费领取资料
高性能架构探索欢迎关注!