网络分层结构

OSI七层模型

OSI 七层模型 是国际标准化组织提出一个网络分层模型,其大体结构以及每一层提供的功能如下图所示:

TCP/IP 五层模型

TCP/IP 五层模型 是目前被广泛采用的一种模型,我们可以将 TCP / IP 模型看作是 OSI 七层模型的精简版本,由以下 5 层组成:

  • 应用层:为应用程序提供交互服务。在互联网中的应用层协议很多,如域名系统DNS、HTTP协议、SMTP协议等。
  • 传输层:负责向两台主机进程之间的通信提供数据传输服务。传输层的协议主要有传输控制协议TCP和用户数据协议UDP。
  • 网络层:选择合适的路由和交换结点,确保数据及时传送。主要包括IP协议。
  • 数据链路层:在两个相邻节点之间传送数据时,数据链路层将网络层交下来的 IP 数据报组装成帧,在两个相邻节点间的链路上传送帧。
  • 物理层:实现相邻节点间比特流的透明传输,尽可能屏蔽传输介质和物理设备的差异。

三次握手

假设发送端为客户端,接收端为服务端。开始时客户端和服务端的状态都是CLOSED

  1. 第一次握手:客户端向服务端发起建立连接请求,客户端会随机生成一个起始序列号x,客户端向服务端发送的字段中包含标志位SYN=1,序列号seq=x。第一次握手前客户端的状态为CLOSE,第一次握手后客户端的状态为SYN-SENT。此时服务端的状态为LISTEN
  2. 第二次握手:服务端在收到客户端发来的报文后,会随机生成一个服务端的起始序列号y,然后给客户端回复一段报文,其中包括标志位SYN=1ACK=1,序列号seq=y,确认号ack=x+1。第二次握手前服务端的状态为LISTEN,第二次握手后服务端的状态为SYN-RCVD,此时客户端的状态为SYN-SENT。(其中SYN=1表示要和客户端建立一个连接,ACK=1表示确认序号有效)
  3. 第三次握手:客户端收到服务端发来的报文后,会再向服务端发送报文,其中包含标志位ACK=1,序列号seq=x+1,确认号ack=y+1。第三次握手前客户端的状态为SYN-SENT,第三次握手后客户端和服务端的状态都为ESTABLISHED此时连接建立完成。

两次握手可以吗?

第三次握手主要为了防止已失效的连接请求报文段突然又传输到了服务端,导致产生问题。

  • 比如客户端A发出连接请求,可能因为网络阻塞原因,A没有收到确认报文,于是A再重传一次连接请求。
  • 连接成功,等待数据传输完毕后,就释放了连接。
  • 然后A发出的第一个连接请求等到连接释放以后的某个时间才到达服务端B,此时B误认为A又发出一次新的连接请求,于是就向A发出确认报文段。
  • 如果不采用三次握手,只要B发出确认,就建立新的连接了,此时A不会响应B的确认且不发送数据,则B一直等待A发送数据,浪费资源。

四次挥手

  1. A的应用进程先向其TCP发出连接释放报文段(FIN=1,seq=u),并停止再发送数据,主动关闭TCP连接,进入FIN-WAIT-1(终止等待1)状态,等待B的确认。
  2. B收到连接释放报文段后即发出确认报文段(ACK=1,ack=u+1,seq=v),B进入CLOSE-WAIT(关闭等待)状态,此时的TCP处于半关闭状态,A到B的连接释放。
  3. A收到B的确认后,进入FIN-WAIT-2(终止等待2)状态,等待B发出的连接释放报文段。
  4. B发送完数据,就会发出连接释放报文段(FIN=1,ACK=1,seq=w,ack=u+1),B进入LAST-ACK(最后确认)状态,等待A的确认。
  5. A收到B的连接释放报文段后,对此发出确认报文段(ACK=1,seq=u+1,ack=w+1),A进入TIME-WAIT(时间等待)状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL(最大报文段生存时间)后,A才进入CLOSED状态。B收到A发出的确认报文段后关闭连接,若没收到A发出的确认报文段,B就会重传连接释放报文段。

第四次挥手为什么要等待2MSL?

  • 保证A发送的最后一个ACK报文段能够到达B。这个ACK报文段有可能丢失,B收不到这个确认报文,就会超时重传连接释放报文段,然后A可以在2MSL时间内收到这个重传的连接释放报文段,接着A重传一次确认,重新启动2MSL计时器,最后A和B都进入到CLOSED状态,若A在TIME-WAIT状态不等待一段时间,而是发送完ACK报文段后立即释放连接,则无法收到B重传的连接释放报文段,所以不会再发送一次确认报文段,B就无法正常进入到CLOSED状态。
  • 防止已失效的连接请求报文段出现在本连接中。A在发送完最后一个ACK报文段后,再经过2MSL,就可以使这个连接所产生的所有报文段都从网络中消失,使下一个新的连接中不会出现旧的连接请求报文段。

为什么是四次挥手?

因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。但是在关闭连接时,当Server端收到Client端发出的连接释放报文时,很可能并不会立即关闭SOCKET,所以Server端先回复一个ACK报文,告诉Client端我收到你的连接释放报文了。只有等到Server端所有的报文都发送完了,这时Server端才能发送连接释放报文,之后两边才会真正的断开连接。故需要四次挥手。

TCP和UDP的区别?

  • TCP面向连接;UDP是无连接的,即发送数据之前不需要建立连接。
  • TCP提供可靠的服务;UDP不保证可靠交付。
  • TCP面向字节流,把数据看成一连串无结构的字节流;UDP是面向报文的。
  • TCP有拥塞控制;UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如实时视频会议等)。
  • 每一条TCP连接只能是点到点的;UDP支持一对一、一对多、多对一和多对多的通信方式。
  • TCP首部开销20字节;UDP的首部开销小,只有8个字节。

HTTP和HTTPS协议

HTTP 协议介绍

HTTP 协议,全称超文本传输协议(Hypertext Transfer Protocol)。顾名思义,HTTP 协议就是用来规范超文本的传输,超文本,也就是网络上的包括文本在内的各式各样的消,具体来说,主要是来规范浏览器和服务器端的行为的。

并且,HTTP 是一个无状态(stateless)协议,也就是说服务器不维护任何有关客户端过去所发请求的消息。这其实是一种懒政,有状态协议会更加复杂,需要维护状态(历史信息),而且如果客户或服务器失效,会产生状态的不一致,解决这种不一致的代价更高。

HTTP 协议通信过程

HTTP 是应用层协议,它以 TCP(传输层)作为底层协议,默认端口为 80. 通信过程主要如下:

  1. 服务器在 80 端口等待客户的请求。
  2. 浏览器发起到服务器的 TCP 连接(创建套接字 Socket)。
  3. 服务器接收来自浏览器的 TCP 连接。
  4. 浏览器(HTTP 客户端)与 Web 服务器(HTTP 服务器)交换 HTTP 消息。
  5. 关闭 TCP 连接。

HTTP协议的特点?

  1. HTTP允许传输任意类型的数据。传输的类型由Content-Type加以标记。
  2. 无状态。对于客户端每次发送的请求,服务器都认为是一个新的请求,上一次会话和下一次会话之间没有联系。
  3. 支持客户端/服务器模式

HTTP状态码有哪些?

HTTP长连接和短连接?

HTTP短连接:浏览器和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。HTTP1.0默认使用的是短连接

HTTP长连接:指的是复用TCP连接。多个HTTP请求可以复用同一个TCP连接,这就节省了TCP连接建立和断开的消耗。

HTTP/1.1起,默认使用长连接。要使用长连接,客户端和服务器的HTTP首部的Connection都要设置为keep-alive,才能支持长连接。

HTTP1.1和 HTTP2.0的区别?

  • 新的二进制格式:HTTP1.1 基于文本格式传输数据;HTTP2.0采用二进制格式传输数据,解析更高效。
  • 多路复用:在一个连接里,允许同时发送多个请求或响应,并且这些请求或响应能够并行的传输而不被阻塞,避免 HTTP1.1 出现的”队头堵塞”问题。
  • 头部压缩,HTTP1.1的header带有大量信息,而且每次都要重复发送;HTTP2.0 把header从数据中分离,并封装成头帧和数据帧,使用特定算法压缩头帧,有效减少头信息大小。并且HTTP2.0**在客户端和服务器端记录了之前发送的键值对,对于相同的数据,不会重复发送。**比如请求a发送了所有的头信息字段,请求b则**只需要发送差异数据**,这样可以减少冗余数据,降低开销。
  • 服务端推送:HTTP2.0允许服务器向客户端推送资源,无需客户端发送请求到服务器获取。

HTTPS 协议介绍

HTTPS 协议(Hyper Text Transfer Protocol Secure),是 HTTP 的加强安全版本。HTTPS 是基于 HTTP 的,也是用 TCP 作为底层协议,并额外使用 SSL/TLS 协议用作加密和安全认证。默认端口号是 443.

HTTPS 协议中,SSL 通道通常使用基于密钥的加密算法,密钥长度通常是 40 比特或 128 比特。

HTTPS 协议优点

保密性好、信任度高。

HTTPS与HTTP的区别?

  1. HTTP是超文本传输协议,信息是明文传输;HTTPS则是具有安全性的ssl加密传输协议。
  2. HTTP和HTTPS用的端口不一样,HTTP端口是80,HTTPS是443。
  3. HTTPS协议需要到CA机构申请证书,一般需要一定的费用。
  4. HTTP运行在TCP协议之上;HTTPS运行在SSL协议之上,SSL运行在TCP协议之上。

DNS 的解析过程?

  1. 浏览器搜索自己的DNS缓存
  2. 若没有,则搜索操作系统中的DNS缓存和hosts文件
  3. 若没有,则操作系统将域名发送至本地域名服务器,本地域名服务器查询自己的DNS缓存,查找成功则返回结果,否则依次向根域名服务器、顶级域名服务器、权限域名服务器发起查询请求,最终返回IP地址给本地域名服务器
  4. 本地域名服务器将得到的IP地址返回给操作系统,同时自己也将IP地址缓存起来
  5. 操作系统将 IP 地址返回给浏览器,同时自己也将IP地址缓存起来
  6. 浏览器得到域名对应的IP地址

浏览器中输入URL返回页面过程?

  1. 解析域名,找到主机 IP。
  2. 浏览器利用 IP 直接与网站主机通信,三次握手,建立 TCP 连接。浏览器会以一个随机端口向服务端的 web 程序 80 端口发起 TCP 的连接。
  3. 建立 TCP 连接后,浏览器向主机发起一个HTTP请求。
  4. 服务器响应请求,返回响应数据。
  5. 浏览器解析响应内容,进行渲染,呈现给用户。

什么是cookie和session?

由于HTTP协议是无状态的协议,需要用某种机制来识具体的用户身份,用来跟踪用户的整个会话。常用的会话跟踪技术是cookie与session。

cookie就是由服务器发给客户端的特殊信息,而这些信息以文本文件的方式存放在客户端,然后客户端每次向服务器发送请求的时候都会带上这些特殊的信息。说得更具体一些:当用户使用浏览器访问一个支持cookie的网站的时候,用户会提供包括用户名在内的个人信息并且提交至服务器;接着,服务器在向客户端回传相应的超文本的同时也会发回这些个人信息,当然这些信息并不是存放在HTTP响应体中的,而是存放于HTTP响应头;当客户端浏览器接收到来自服务器的响应之后,浏览器会将这些信息存放在一个统一的位置。 自此,客户端再向服务器发送请求的时候,都会把相应的cookie存放在HTTP请求头再次发回至服务器。服务器在接收到来自客户端浏览器的请求之后,就能够通过分析存放于请求头的cookie得到客户端特有的信息,从而动态生成与该客户端相对应的内容。网站的登录界面中“请记住我”这样的选项,就是通过cookie实现的。

cookie工作流程

  1. servlet创建cookie,保存少量数据,发送给浏览器。
  2. 浏览器获得服务器发送的cookie数据,将自动的保存到浏览器端。
  3. 下次访问时,浏览器将自动携带cookie数据发送给服务器。

session原理:首先浏览器请求服务器访问web站点时,服务器首先会检查这个客户端请求是否已经包含了一个session标识、称为SESSIONID,如果已经包含了一个sessionid则说明以前已经为此客户端创建过session,服务器就按照sessionid把这个session检索出来使用,如果客户端请求不包含session id,则服务器为此客户端创建一个session,并且生成一个与此session相关联的独一无二的sessionid存放到cookie中,这个sessionid将在本次响应中返回到客户端保存,这样在交互的过程中,浏览器端每次请求时,都会带着这个sessionid,服务器根据这个sessionid就可以找得到对应的session。以此来达到共享数据的目的。 这里需要注意的是,session不会随着浏览器的关闭而死亡,而是等待超时时间。

Cookie和Session的区别?

  • 作用范围不同,Cookie 保存在客户端,Session 保存在服务器端。
  • 有效期不同,Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般失效时间较短,客户端关闭或者 Session 超时都会失效。
  • 隐私策略不同,Cookie 存储在客户端,容易被窃取;Session 存储在服务端,安全性相对 Cookie 要好一些。
  • 存储大小不同, 单个 Cookie 保存的数据不能超过 4K;对于 Session 来说存储没有上限,但出于对服务器的性能考虑,Session 内不要存放过多的数据,并且需要设置 Session 删除机制。

什么是对称加密和非对称加密?

对称加密:通信双方使用相同的密钥进行加密。特点是加密速度快,但是缺点是密钥泄露会导致密文数据被破解。常见的对称加密有AESDES算法。

非对称加密:它需要生成两个密钥,公钥和私钥。公钥是公开的,任何人都可以获得,而私钥是私人保管的。公钥负责加密,私钥负责解密;或者私钥负责加密,公钥负责解密。这种加密算法安全性更高,但是计算量相比对称加密大很多,加密和解密都很慢。常见的非对称算法有RSADSA

滑动窗口机制

TCP 利用滑动窗口实现流量控制。流量控制是为了控制发送方发送速率,保证接收方来得及接收。 TCP会话的双方都各自维护一个发送窗口和一个接收窗口。接收窗口大小取决于应用、系统、硬件的限制。发送窗口则取决于对端通告的接收窗口。接收方发送的确认报文中的window字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将接收方的确认报文window字段设置为 0,则发送方不能发送数据。

TCP头包含window字段,16bit位,它代表的是窗口的字节容量,最大为65535。这个字段是接收端告诉发送端自己还有多少缓冲区可以接收数据。于是发送端就可以根据这个接收端的处理能力来发送数据,而不会导致接收端处理不过来。接收窗口的大小是约等于发送窗口的大小。

详细讲一下拥塞控制?

防止过多的数据注入到网络中。 几种拥塞控制方法:慢开始( slow-start )、拥塞避免( congestion avoidance )、快重传( fast retransmit )和快恢复( fast recovery )。

慢开始

把拥塞窗口 cwnd 设置为一个最大报文段MSS的数值。而在每收到一个对新的报文段的确认后,把拥塞窗口增加至多一个MSS的数值。每经过一个传输轮次,拥塞窗口 cwnd 就加倍。 为了防止拥塞窗口cwnd增长过大引起网络拥塞,还需要设置一个慢开始门限ssthresh状态变量。

当 cwnd < ssthresh 时,使用慢开始算法。

当 cwnd > ssthresh 时,停止使用慢开始算法而改用拥塞避免算法。

当 cwnd = ssthresh 时,既可使用慢开始算法,也可使用拥塞控制避免算法。

拥塞避免

让拥塞窗口cwnd缓慢地增大,每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍。这样拥塞窗口cwnd按线性规律缓慢增长。

无论在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有收到确认),就要把慢开始门限ssthresh设置为出现拥塞时的发送 方窗口值的一半(但不能小于2)。然后把拥塞窗口cwnd重新设置为1,执行慢开始算法。这样做的目的就是要迅速减少主机发送到网络中的分组数,使得发生 拥塞的路由器有足够时间把队列中积压的分组处理完毕。

快重传

有时个别报文段会在网络中丢失,但实际上网络并未发生拥塞。如果发送方迟迟收不到确认,就会产生超时,就会误认为网络发生了拥塞。这就导致发送方错误地启动慢开始,把拥塞窗口cwnd又设置为1,因而降低了传输效率。

快重传算法可以避免这个问题。快重传算法首先要求接收方每收到一个失序的报文段后就立即发出重复确认,使发送方及早知道有报文段没有到达对方。

发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待重传计时器到期。由于发送方尽早重传未被确认的报文段,因此采用快重传后可以使整个网络吞吐量提高约20%。

快恢复

当发送方连续收到三个重复确认,就会把慢开始门限ssthresh减半,接着把cwnd值设置为慢开始门限ssthresh减半后的数值,然后开始执行拥塞避免算法,使拥塞窗口缓慢地线性增大。

在采用快恢复算法时,慢开始算法只是在TCP连接建立时和网络出现超时时才使用。 采用这样的拥塞控制方法使得TCP的性能有明显的改进。

ARP协议

ARP解决了同一个局域网上的主机和路由器IP和MAC地址的解析。

  • 每台主机都会在自己的ARP缓冲区中建立一个ARP列表,以表示IP地址和MAC地址的对应关系。
  • 当源主机需要将一个数据包要发送到目的主机时,会首先检查自己 ARP列表中是否存在该 IP地址对应的MAC地址,如果有,就直接将数据包发送到这个MAC地址;如果没有,就向本地网段发起一个ARP请求的广播包,查询此目的主机对应的MAC地址。此ARP请求数据包里包括源主机的IP地址、硬件地址、以及目的主机的IP地址。
  • 网络中所有的主机收到这个ARP请求后,会检查数据包中的目的IP是否和自己的IP地址一致。如果不相同就忽略此数据包;如果相同,该主机首先将发送端的MAC地址和IP地址添加到自己的ARP列表中,如果ARP表中已经存在该IP的信息,则将其覆盖,然后给源主机发送一个 ARP响应数据包,告诉对方自己是它需要查找的MAC地址。
  • 源主机收到这个ARP响应数据包后,将得到的目的主机的IP地址和MAC地址添加到自己的ARP列表中,并利用此信息开始数据的传输。
  • 如果源主机一直没有收到ARP响应数据包,表示ARP查询失败。

参考文章:

[1] https://snailclimb.gitee.io/javaguide/#/

[2] https://github.com/Tyson0314/Java-learning/blob/master/%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E9%AB%98%E9%A2%91%E9%9D%A2%E8%AF%95%E9%A2%98.md