计算机网络常见面试题

 

一、HTTP

 

1、Cookie和Session的联系与区别?

联系

(1)都是保存用户信息的机制

(2)Session的运行依赖Session ID,而Session ID存在Cookie中,叫做JSESSIONID。如果浏览器禁用了Cookie,则Session也会失效。当然,Session的运行也可以用其他方式实现,比如在URL中传递Session ID。

区别

(1)存储内容:Cookie只能存储ASCII码,而Session可以存储任何类型的数据  ->  如果需要考虑数据复杂性则选择Session;

(2)存储位置:Cookie存储在浏览器中,容易被恶意查看,而Session存储在服务器,相对于Cookie更安全  ->  如果非要将一些隐私数据存在Cookie中,可以将Cookie值进行加密,然后在服务器进行解密(不一定);浏览器会限制Cookie的大小和数量,服务器则一般不会.

(3)存储开销:Cookie不会给服务器带来额外的开销,而Session由于存在服务器上,会给服务器带来一些开销  ->  对于大型网站,如果用户的所有信息都存储在Session中,那么开销是非常大的,因此不建议将所有的用户信息都存储到Session中;若考虑减轻服务器负担,应当使用Cookie.

 

2、Cookie概述

(1)为什么引入Cookie?

HTTP协议是无状态的,主要是为了让HTTP协议尽可能简单,使得它能够处理大量事务。而有一些场景又需要维持状态,因此HTTP/1.1引入Cookie来保存状态信息。

(2)什么是Cookie?

Cookie是服务器发给客户端的特殊信息,以文本的形式存在客户端。当浏览器向同一服务器再次发起请求时,它会被携带上,用于告知服务器两个请求是否来自同一浏览器(“请记住我”功能就是通过Cookie实现的)。由于以后每次请求都需要携带Cookie数据,因此会带来额外的性能开销,尤其是在移动环境下。

Cookie可以分为会话期Cookie和持久性Cookie。会话期Cookie在浏览器关闭之后就会被自动删除,即仅在会话期内有效;持久性Cookie则是在浏览器关闭之后依然可以存在,通过指定过期时间(Expires)来实现。

(3)Cookie的用途

会话状态管理(如用户登录状态、购物车、游戏分数或其他需要记录的信息)、个性化设置(如用户自定义设置、主题等)、浏览器行为跟踪(如跟踪分析用户行为等)

(4)Cookie的设置以及发送过程

计算机网络常见面试题_第1张图片

如上图所示,服务器发送的响应报文包含Set-Cookie首部字段,客户端得到响应报文之后把Cookie内容保存在浏览器中;客户端之后对同一个服务器发送请求时,会从浏览器中取出Cookie信息并通过Cookie请求首部字段发送给服务器。

(5)Cookie的属性

1)通过设置过期时间Expires,让Cookie成为持久性的Cookie

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2020 07:28:00 GMT;

2)通过设施Domain指定哪些主机可以接受Cookie,通过设置Path指定主机的哪些路径下可以接受Cookie(Cookie的作用域)

如果设置了 Domain,则子域名一般也可以接受,如,如果设置 Domain=mozilla.org,则 Cookie 也包含在子域名中(如 developer.mozilla.org)。如果不设置Domain,则默认当前文档的主机(不包含子域名)。

如设置Path=/docs,则/docs、/docs/Web/、/docs/Web/HTTP等地址都会被匹配到。

3)使用HttpOnly指定Cookie不能被JavaScript脚本调用

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2020 07:28:00 GMT; Secure; HttpOnly

标记为HttpOnly的Cookie不能被JavaScript脚本调用。跨站脚本攻击(XSS)常常使用JavaScript的document.cookie API(可创建新的Cookie,可访问非HttpOnly标记的Cookie)窃取用户的Cookie信息,因此使用HttpOnly标记可以在一定程度上避免XSS攻击。

document.cookie = "yummy_cookie=choco";
document.cookie = "tasty_cookie=strawberry";
console.log(document.cookie);

4)使用Secure指定Cookie只能通过被HTTPS协议加密过的请求发送给服务器

不过即使设置了Secure标记,敏感信息也不应该通过Cookie传输,因为Cookie有其固有的不安全性,Secure标记也无法提供确实的安全保障。

 

3、Session概述

(1)什么是Session

除了可以将用户信息通过Cookie存储在用户浏览器中,也可以通过Session存储在服务器端(可存储在服务器上的文件、数据库、内存中或者Redis这种效率更高的内存型数据库中)。Session是服务器端的机制,存储在服务器端的信息更加安全。

(2)使用Session维护用户登录状态的过程

1)用户进行登录时,用户提交包含用户名和密码的表单,放入HTTP请求报文中;

2)服务器验证该用户名和密码,如果正确则将用户信息存储到Redis中,它在Redis中的Key称为Session ID;

3)服务器返回的响应报文的Set-Cookie首部字段包含了这个Session ID,客户端收到响应报文之后将该Cookie值存入浏览器中;

4)客户端之后对同一个服务器发起请求时会包含该Cookie值,服务器收到之后提取出Session ID,从Redis中取出用户信息,继续之前的业务操作.

应该注意Session ID的安全性问题,不能让它被恶意攻击者轻易获取,因此不能产生一个统一被猜到的Session ID值。此外,还需要经常重新生成Session ID。在安全性要求极高的场景下,如转账等操作,除了使用Session管理用户状态之外,还需要对用户进行重新验证,比如重新输入密码,或者使用短信验证码等方式。

(3)Session的实现方式

1)通过Cookie实现

上面维护用户登录状态的过程就是Cookie实现的。

计算机网络常见面试题_第2张图片

2)通过URL回写实现

当浏览器禁用Cookie时,此时无法使用Cookie来保存用户信息(只能使用Session)。同时,也不能将Session ID存放到Cookie中。应该使用URL重写技术,将Session ID作为URL的参数进行传递。

 

4、HTTP和HTTPS的区别

1)HTTPS需要到CA申请证书,HTTP不需要;

2)HTTPS密文传输,HTTP明文传输;

3)连接方式不同,HTTPS默认使用443端口,HTTP默认使用80端口;

4)HTTPS = HTTP + 加密 + 认证 + 完整性保护,较HTTP安全 (是有状态的);

5)HTTPS相比于HTTP,虽然提供了安全保证,但是势必会带来一些时间上的损耗,如握手和加密等过程,是否使用HTTPS需要根据具体情况在安全和性能方面做出权衡。

计算机网络常见面试题_第3张图片

 

5、HTTP概述

(1)HTTP是什么?

HTTP也就是超文本传输协议,由客户端程序和服务器程序实现,客户端程序和服务器程序通过交换HTTP报文进行会话。HTTP定义了这些报文的结构以及报文交换的方式,当用户请求一个Web页面时,浏览器向服务器发出对该页面中所包含对象的HTTP请求报文,服务器接收请求并返回包含这些对象的HTTP响应报文。

(2)报文结构

(3)报文交换的方式

(4)HTTP请求的过程(在浏览器中输入一个URL,敲回车,中间会有哪些过程)

总的来说分为以下几个过程:DNS解析 -> TCP 连接 -> 发送HTTP请求 -> 服务器处理请求并返回HTTP响应报文 -> 浏览器解析渲染页面 -> 连接结束。

1)DNS解析:其实就是将域名映射成IP地址的过程,这种对应关系可以从浏览器缓存中获取,如果没有则去系统hosts文件(系统缓存)中获取,如果没有再去路由器DNS缓存中获取,最后依次到IPS服务器缓存(DNS运营商)->根域名服务器缓存 -> 顶级域名服务器缓存 -> 主域名服务器缓存中获取。

2)TCP连接:有三次握手的过程

3)发送HTTP请求:发送HTTP请求的过程就是构建HTTP请求报文并通过TCP协议发送到服务器指定端口(HTTP协议为80/8080端口,HTTPS协议为443端口)。HTTP请求报文由三部分组成:请求行、请求报头、请求正文。

请求行:常用的请求方法有:GET、POST、PUT、DELETE、OPTIONS、HEAD。

GET index.html HTTP/1.1

请求报头:客户端(浏览器、curl命令等)通过它向服务器传递请求的附加信息和客户端自身的信息。常见的请求报头有:Accept、Accept-Charset、Accept-Encoding、Accept-Language、Authorization、User-Agent、Cache-Control、Cookie、Connection、Content-Type等。其中,Accept告知服务器客户端接受哪些类型的信息,Accept-Encoding告知服务器客户端接受的编码方式。Connection设置为keep-alive告诉客户端本次HTTP请求结束之后并不需要关闭TCP连接,这样使得下次HTTP请求可以使用相同的TCP通道,节省TCP连接建立的时间。Content-Type表示请求正文相关信息,比如,现在的web应用通常使用REST架构,请求的数据格式一般为JSON,这就需要设置Content-Type:application/json。

请求正文:当使用POST、PUT等方法时,通常需要客户端向服务器传递数据,这些数据就存储在请求正文中。

4)服务器处理请求并返回HTTP响应报文:后端在固定的端口接收TCP报文(对应于Socket),然后对TCP连接进行处理,对HTTP协议进行解析,并按照报文格式进一步封装成HTTP Request对象,供上层使用(对应于web服务器,如Tomcat、Jetty等)。HTTP响应报文由3部分组成:状态码、响应报头、响应报文。

状态码:就是一个3位数,第一个数字代表响应的类别。常见的状态码有200、204、301、302、304、400、401、403、422、500。

1xx(指示信息):表示请求已被接收,继续等待处理

2xx(请求成功):表示请求已被成功接收、理解、接受

3xx(重定向):要完成请求必须进行更进一步的操作

4xx(客户端错误):请求有语法错误或请求无法实现

5xx(服务端错误):服务器未能实现合法的请求

响应报头:常见的响应报头字段有Server、Connection等

响应报文:服务器返回给客户端的文本信息,通常有HTML、CSS、JavaScript、图片等文件。

5)浏览器解析渲染页面:浏览器边解析边渲染。首先浏览器解析HTML文件构建DOM树,然后解析CSS文件构建渲染树,等渲染树构建完成后,浏览器开始布局渲染树并将其绘制到屏幕上。

6)连接结束:有四次挥手的过程

参考:https://segmentfault.com/a/1190000006879700 

(5)网页响应慢如何解决?如果一个页面好几十秒才显示内容,该如何快速完成页面的加载?

为了尽快地加载资源,我们需要尽可能不从网络中加载资源,因此我们需要合理使用缓存,将资源放在浏览器端。如果资源必须从网络中架子啊,则需要缩短连接时间(进行DNS优化)、减少响应内容大小(对内容进行压缩)、减少加载的资源数量。当资源到达浏览器之后,浏览器开始进行解析渲染,浏览器中最耗时的部分是reflow,所以应该考虑如何减少reflow的次数。

(6)GET和POST有什么区别?

(7)301和 302有什么区别?HTTP缓存?

 

6、HTTPS概述

(1)HTTPS是什么?为什么引入HTTPS?

HTTPS就是HTTP over SSL,在HTTP传输上增加了SSL安全套接字层,通过机密性数据完整性身份鉴别为HTTP事务提供安全保证。其工作原理大致为,在发送方,SSL会将数据加密并将加密后数据送往TCP套接字,而在接收方,SSL读取TCP套接字的数据并解密,把解密后的数据交给应用层。HTTPS采用混合加密机制,使用非对称加密传输密钥保证 “传输安全” ,使用对称加密保证 “通信效率” 。

HTTPS并不是新协议,而是让HTTP先和SSL(Secure Sockets Layer)通信,再让SSL和TCP通信,即,HTTPS使用隧道进行通信。

之所以引入HTTPS,是因为HTTP有以下安全性问题:1)使用明文进行通信,内容可能会被窃听; 2)不验证通信方的身份,通信方的身份有可能遭遇伪装; 3)无法证明报文的完整性,报文有可能遭篡改

通过使用SSL,HTTPS具有了加密(防窃听)、认证(防伪装)和完整性保护(防篡改)。

(2)HTTPS采用的加密方式(加密)

常用的加密方式有对称密钥加密、非对称密钥加密两种。

对称密钥加密(Symmetric-Key Encryption)就是加密和加密使用同一密钥。其优点是运算速度快,缺点是无法安全地将密钥传输给通信方

非对称密钥加密(公开密钥加密,Public-Key Encryption)就是加密和解密使用不同的密钥。其优点是可以更安全地将公开密钥传输给通信发送方,缺点是运算速度慢

公开密钥所有人都可以获得,通信发送方获得接收方的公开密钥之后,就可以使用公开密钥进行加密,接收方收到通信内容后使用私有密钥解密。

非对称密钥除了用来加密,还可以用来进行签名。因为私有密钥无法被其他人获得,因此,通信发送方使用其私有密钥进行签名,通信接收方使用发送方的公开密钥对签名进行解密,就能判断这个签名是否正确。

HTTPS采用混合加密机制:1)使用非对称密钥加密方式传输对称密钥加密方式所需要的Secret Key,从而保证安全性; 2)获取到Secret Key后,再使用对称密钥加密方式进行通信,从而保证效率

(3)认证

HTTPS通过使用证书(由数字证书认证机构,Certificate Authority,即CA,提供,它是客户端与服务器双方都可信赖的第三方机构)来对通信方进行认证。其流程大致如下,1)服务器的运营人员向CA提出公开密钥的申请,CA在判明提出申请者的身份之后,会对已申请的公开密钥做数字签名,然后分配这个已签名的公开密钥,并将该公开密钥放入公开密钥证书后绑定在一起。2)进行HTTPS通信时,服务器会把证书发送给客户端,客户端取得其中的公开密钥之后,先使用数字签名进行验证,如果验证通过,就可以开始通信了。

(4)完整性保护

SSL提供报文摘要功能来进行完整性保护HTTP也提供了MD5报文摘要功能,但不是安全的。例如报文内容被篡改之后,同时重新计算MD5的值,通信接收方是无法意识到发生了篡改的。而HTTPS的报文摘要功能之所以安全,是因为它结合了加密和认证两个操作。加密之后的报文,遭到篡改之后,也很难重新计算报文摘要,因为无法轻易获取明文。

(5)HTTPS的过程

1)客户端发送其支持的算法列表以及一个不重数。不重数就是在协议的生存期只使用一次的数,用于防止重放攻击,每个TCP会话使用不同的不重数,可以使加密密钥不同,重放记录无法通过完整性检查

2)服务器从该列表中选择一种对称加密算法(例如AES)、一种公钥加密算法(例如RSA)和一种报文鉴别码算法,然后把它的选择、整数、一个不重数返回给客户端

3)客户端通过CA提供的公钥验证证书,成功后提取服务器的公钥,生成一个前主密钥PMS并发送给服务器

4)客户端和服务器独立地从PMS和不重数中计算出仅用于当前会话的主密钥MS,然后通过MS生成密码和报文鉴别码密钥。此后客户端和服务器之间发送的所有报文均被加密和鉴别

如果用简洁一点的话总结,如下:

1)浏览器将支持的加密算法信息发送给服务器

2)服务器选择一套浏览器支持的加密算法,以证书的形式回发给浏览器

3)浏览器验证证书合法性,并结合证书公钥加密信息发送给服务器(浏览器使用公钥加密信息)

4)服务器使用私钥解密信息,验证哈希,加密响应信息回发给浏览器(服务器使用私钥解密信息)

(6)HTTPS的缺点

因为需要进行加密解密等过程,因此速度会更慢

需要支付证书授权的高额费用

 

二、TCP/UDP

 

1、TCP三次握手的过程?为什么要三次握手?

(1)TCP三次握手的过程

三次握手的过程如下图所示,

计算机网络常见面试题_第4张图片

初始时客户端A和服务器B均处于CLOSED状态,服务器B创建传输进程控制块TCB并进入LISTEN状态,监听端口是否收到连接请求。

第一次握手:建立连接时,客户端A向服务器B发送SYN包(连接请求报文,seq = j,SYN = 1,ACK = 0),并进入SYN-SENT状态(同步已发送状态),等待服务器确认;

第二次握手:服务器B收到SYN包,进入SYN-RECV状态(同步已接收状态)。如果同意建立连接,则会给客户端A发送一个SYN-ACK 包(连接响应报文,ack = j+1,SYN = 1,ACK = 1,seq = k); 也就是必须确认客户的SYN(ack = j + 1),同时自己也发送一个SYN包(seq = k),即SYN+ACK包;

第三次握手:客户端A收到服务器B的SYN-ACK包,向服务器发送ACK(再进行一次确认,ack = k+1),然后进入ESTABLISHED状态,服务器收到之后也进入ESTABLISHED状态,完成三次握手。

总之,目的是建立全双工、可靠的连接,这种连接时占用通信线路的,需要释放。

第一次握手的SYN包不可以携带数据,但要消耗一个序号。第二次握手的ACK包可以携带数据,不携带的话则不消耗序号。

第二次握手传回ACK是为了告诉客户端已接收其连接请求,而传回SYN则是为了建立从服务端到客户端的连接。

第三次握手中,客户端要稍早于服务器进入ESTABLISHED状态,稍早于服务器建立连接。

(2)三次握手的原因

1)从信息对等的角度看,A、B分别要确认自己和对方的发送、接收能力均正常。第二次握手后B还不能确定自己的发送能力和A的接收能力。

通信其实就是数据的发送与接收,而三次握手最主要的目的就是为了建立全双工的通信,双方均需要确认自己与对方的发送与接收都是正常的。第一次握手客户端告诉服务器自己可以正常发送数据;第二次握手服务器告诉客户端自己可以正常接收、发送数据;第三次握手客户端告诉服务器自己可以正常接收数据。总之,三次握手就能确认双方收发功能正常、双方之间的网络正常,缺一不可。

2)三次握手还为了确定序号(Sequence Number)的初始值

通信双方要告知对方自己初始化的序号值,序号用于TCP拼接数据,避免乱序或者丢失数据。因此,在第二次握手之后,客户端还要发送确认报文表明自己已经知道服务器要初始化的序号了。

3)三次握手还为了防止失效的连接请求到达服务器,让服务器错误打开连接(A的超时连接请求可能会在双方释放连接后到达B,B会误认为是A发送了新的连接请求,然后创建连接,服务资源被浪费)

客户端发送的连接请求如果在网络中滞留,那么就会隔很长一段时间才能收到服务器发回的连接确认。而客户端在等待一个超时重传时间之后,就会重新发送连接请求。当客户端执行了第三次握手之后,它就会忽略服务器之后发回的对滞留连接请求(滞留的连接请求最后也是会到达服务器的)的连接确认,不进行第三次握手,因此就不会再次打开连接。

 

2、TCP四次挥手的过程?为什么要四次挥手?

(1)TCP四次挥手的过程

四次挥手的过程如下图所示,

计算机网络常见面试题_第5张图片

第一次挥手:当Client没有要发送的数据时,Client向Server发送一个FIN(连接终止报文,FIN = 1),用来关闭Client到Server的数据传送,Client进入FIN-WAIT-1状态;

第二次挥手:Server收到FIN后,发送一个ACK(确认报文)给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态,Client收到后进入FIN-WAIT-2状态,此时,TCP处于半关闭状态

第三次挥手:当Server也准备释放连接时,Server向Client发送一个FIN(连接终止报文,FIN = 1,重发ACK = 1),用来关闭Server到Client的数据传送,Server进入LAST_ACK状态;

第四次挥手:Client收到FIN后,发送一个ACK(再进行一次确认,确认序号为收到序号+1)给Server。Server收到确认后进入CLOSED状态,而Client需要等待2MSL后进入CLOSED状态,完成四次挥手

可以发现,三次握手时,客户端比服务器先进入ESTABLISHED状态;四次挥手时,服务器比客户端先进入CLOSED状态。

在第四次挥手中,等待2MSL的原因:

1)确保有足够的时间让对方收到最后一个ACK包。MSL是最大报文段寿命,等待2MSL可以保证Client发送的最后一个确认报文被B接收,如果该报文丢失,Server会超时重传之前的FIN+ACK报文,保证Server正常进入CLOSED状态

2)避免新旧连接混淆在一起。2MSL后,本连接中的所有报文就都会从网络中消失,防止下一个连接被旧的连接请求报文干扰。

在第二次挥手中,为什么服务器会有CLOSE_WAIT状态:

客户端发送了FIN连接释放报文之后,服务器收到了这个报文,就进入CLOSE_WAIT状态。这个状态是为了让服务器端发送完还未传送完毕的数据,传送完毕之后,服务器会发送FIN连接释放报文。

服务器出现大量CLOSE_WAIT状态的原因:

对方关闭socket连接,我方忙于读或写,没有及时关闭连接。出现这种情况,通常需要:检查代码(特别是释放资源的代码)、检查配置(特别是处理请求的线程配置)。查看处于CLOSE_WAIT状态的连接数如下图所示:

线上大量CLOSE_WAIT的原因排查案例:https://cloud.tencent.com/developer/article/1381359

此外,可以参考:https://blog.51cto.com/net881004/2164020?source=dra

https://blog.51cto.com/net881004/2164024

https://help.aliyun.com/knowledge_detail/41334.html?spm=a2c6h.13066369.0.0.3cbb2f983Qd6AN

http://blog.huoding.com/2016/01/19/488

关闭 CLOSE_WAIT状态连接可以参考:http://www.manongjc.com/detail/13-erkkovgeguilsji.html

 

(2)四次挥手的原因

TCP是全双工通信,两个方向的连接需要单独断开(被动断开的一方可能还有数据要发给主动断开的一方)。

 

3、TCP和UDP的区别

1)面向连接 vs 无连接

TCP是面向连接的,发送数据前必须先建立连接,发送某些预备报文段;UDP无连接,发送数据前不需要建立连接。

2)双方通信 vs 多方通信

TCP连接时点对点的,只能是单个发送方和单个接收方之间的连接;UDP支持一对一、一对多和多对多通信。

3)可靠性 vs 不可靠

TCP提供可靠的交付服务,通过TCP传送的数据无差错、不丢失、不重复,按序到达;UDP使用尽最大努力交付,不保证可靠性,主机不需要维持复杂的连接状态。

4)面向字节流 vs 面向报文

TCP是面向字节流的,以字节流进行传输,TCP不保证接收方的数据块和发送方的数据块具有对应大小的关系,但接收方的字节流必须和发送方的字节流完全一样,应用程序必须有能力识别收到的字节流,把它还原成应用层数据;UDP面向报文,以数据报进行传输(数据报协议),对应用层报文添加首部后就交付IP层(不合并、不拆分、保留上面传下来的报文的边界)。

5)有拥塞控制 vs 没有拥塞控制

TCP有拥塞控制;UDP没有拥塞控制,网络拥塞不会降低源主机的发送速率,这对某些实时应用很重要,如视频会议。

此外,TCP的报头是重量级的而UDP的报头是轻量级的(TCP首部为20-60个字节,其中20字节是固定的,UDP首部为8个字节)-> TCP报文长度是动态的而UDP则不是(TCP报文长度是根据接收方的窗口大小和当前网络拥塞情况决定的,UDP则是不合并、不拆分、保留上面传下来的报文的边界) -> TCP所需资源多(确认、流量控制、计时器、连接管理等开销)而UDP所需资源少 -> TCP速度慢而UDP速度快 -> TCP通信数据可靠而UDP不可靠。

小结:

TCP(Transmission Control Protocol,传输控制协议)是面向连接的,提高可靠交付,有流量控制,拥塞控制,提供全双工通信,面向字节流(把应用层传下来的报文看成字节流,把字节流组织成大小不等的数据块),每一条TCP连接只能是点对点的(一对一)。TCP适用于文件传输、发送和接收邮件、远程登录、重要状态的更新等场景。

UDP(User Datagram Protocol,用户数据报协议)是无连接的,尽最大可能交付,没有拥塞控制,面向报文(对于应用程序传下来的报文不合并也不拆分,只是添加UDP首部。应用也因此需要自己控制好应用层数据大小),支持一对一、一对多、多对一和多对多的交互通信。UDP适用于视频传输、直播、实时通信(QQ语音、QQ视频)等场景。

计算机网络常见面试题_第6张图片

 

4、TCP的拥塞控制

(1)拥塞、拥塞控制的定义

网络拥塞指的是在分组交换网络中传输的分组数目太多时,由于存储转发节点的资源有限而造成网络传输性能下降的情况。网络拥塞是一种持续过载的网络状态,此时用户对网络资源(链路带宽、存储空间、处理器处理能力等)的需求超过了固有的处理能力和容量。拥塞控制所起的作用如下图所示。

计算机网络常见面试题_第7张图片

(2)拥塞控制与流量控制的区别

如果网络出现拥塞,分组将会丢失,此时发送方会继续重传,从而导致网络拥塞程序更高。因此,当出现拥塞时,应当控制发送方的发送速率。在这一点上,拥塞控制和流量控制很像。

但是,拥塞控制指的是通过减少注入网络的数据,减轻路由器和链路的负担,降低整个网络的拥塞程度,这是一个全局性的问题,涉及网络中的所有路由器和主机,而流量控制是为了让接收方来得及接收,流量控制是一个端到端的问题

拥塞控制是发送方通过自己的状态变量——拥塞窗口cwnd来控制发送速率。而流量控制主要是根据接收窗口大小来控制发送速率,实际发送窗口大小是rwnd(接收端TCP报文的窗口大小字段,如果为0则发送方不能发送数据)和cwnd(拥塞窗口大小)中的较小值。

总之,手段很像(都是通过控制发送速率),但出发点不同(拥塞控制是为了降低整个网络的拥塞程序,流量控制是为了让接收方来得及接收)。

(3)TCP的拥塞控制算法

TCP的拥塞控制算法包括:慢启动拥塞避免快重传快恢复。其中,慢启动和拥塞避免是TCP的强制部分,差异在于对收到的ACK做出反应时拥塞窗口增加的方式,慢启动比拥塞避免增加得更快。快恢复是推荐部分,对TCP发送方不是必须的。

1)慢启动

慢启动的思路是不要一开始就发送大量数据,而是先探测以下网络的拥塞程度,从小到大逐渐增加拥塞窗口的大小(注意,拥塞窗口cwnd只是一个状态变量,跟发送窗口不同)。

慢启动的具体流程如下,拥塞窗口以1个MSS(最大单个报文段长度)开始,即cwnd = 1,在没有出现丢包时,每当传输的报文段首次收到一个ACK确认,拥塞窗口的大小就加1(单位是MSS,最大单个报文段长度),显然,拥塞窗口的增长将随RTT呈指数级增长(1个、2个、4个、8个......,即每经过一个RTT往返时间,拥塞窗口的大小就会翻倍,发送速率也会翻倍)。如果出现丢包,就将拥塞窗口减半,进入拥塞避免阶段。

结束慢启动的情况有:1)发生超时事件,发送方先将慢启动阈值设为cwnd / 2,再将cwnd设为1,重新开始慢启动; 2)当拥塞窗口达到慢启动阈值时就结束慢启动而进入拥塞避免模式; 3)如果检测到三个冗余的ACK,TCP就会执行快重传并进入快恢复状态。

2)拥塞避免

当窗口大小达到慢启动阈值或出现丢包时,进入拥塞避免阶段。

拥塞避免的具体流程如下,窗口每轮次加1,呈线性增长(即,每个RTT后将cwnd保守地加1,而不再是将cwnd翻倍。因为一旦进入拥塞避免阶段,cwnd值大约是上次拥塞时的1/2,距离拥塞并不遥远)。

当发生超时事件时,拥塞避免和慢启动一样,将慢启动阈值设置为cwnd / 2,然后将cwnd设为1,重新开始慢启动。

3)快重传

当收到对一个报文的三个重复的ACK时,认为这个报文的下一个报文丢失了,进入快重传阶段。

快重传要求接收方在收到一个失序的报文段后就立即发出重复确认,而不要等到自己发送数据时捎带确认(为的是让发送方及早直到有报文段没有到达对方,可提高网络吞吐量约20%)。

4)快恢复

快重传完成后进入快恢复阶段。为什么不是慢启动,而是快恢复?因为至少收到了3个Duplicated Acks,说明网络也不那么糟糕,可以快速恢复。

快恢复的流程为,将慢启动阈值修改为当前拥塞窗口大小的一半,同时让慢启动阈值等于拥塞窗口大小,使得马上进入拥塞避免阶段,重复上述过程。

注意,有时个别报文段丢失,但网络中并没有出现拥塞,如果使用慢启动会降低传输效率。这时,应该使用快重传来让发送方尽早知道出现了个别分组的丢失(快重传要求接收端不要等待自己发送数据时再捎带确认,而是要立即发送确认,即使收到了乱序的报文段也要立即发出对已收到报文段的重复确认)。当收到三个冗余ACK后就知道出现了报文段丢失的情况,会立即重传并进入快恢复状态。在快恢复中,会调整慢启动阈值为cwnd / 2,并进入拥塞避免阶段。

三次重复的ACK,可能是丢包引起的(丢包可能是网络拥塞导致的,也可能是信号失真导致的),也可能是乱序引起的。参考:https://www.zhihu.com/question/280521822

小结:

1)可以注意到,慢启动每个轮次都将cwnd加倍,这样会让cwnd增长速度非常快,使得发送方发送速率增长速度过快,网络拥塞的可能性也就越来越高。因此,设置一个慢启动阈值ssthresh的目的在于,使得cwnd >= ssthresh时,要通过放慢cwnd的增长速度,来避免网络拥塞,也就是进入拥塞避免阶段(大家都要约束好自己的发送速率,不能让某个人占用太多公共带宽资源)。

2)如下图所示为《计算机网络——自顶向下的方法》介绍的Reno算法,它是TCP拥塞控制算法的一种实现。可以看到,首先在慢启动阶段,拥塞窗口cwnd从1开始随着RTT指数级增长,当cwnd的大小达到慢启动阈值时进入拥塞避免阶段。在拥塞避免阶段中,cwnd随着RTT线性增长,当出现超时现象时,发送方先将慢启动阈值设为cwnd / 2,再将cwnd设为1,重新开始慢启动。当新的拥塞避免阶段中遇到3-ACK时,即检测到3个冗余的ACK时,发送方TCP就会执行快重传并进入快恢复状态。快恢复阶段中,将慢启动阈值修改为当前拥塞窗口大小的一半,同时让慢启动阈值等于拥塞窗口大小,使得马上进入拥塞避免阶段,重复上述过程。

计算机网络常见面试题_第8张图片

 

5、TCP概述

(1)滑动窗口是怎么变化的?(TCP滑动窗口机制)

滑动窗口是缓存的一部分,用来暂时存放字节流,其以字节为单位。发送方和接收方各有一个窗口,接收方通过 TCP 报文段中的窗口字段告诉发送方自己的窗口大小,发送方根据这个值和其它信息设置自己的窗口大小。

发送窗口内的字节都允许被发送,窗口左边界之外是已发送并收到确认的序号,窗口右边界之外是不允许发送的序号。如果发送窗口左部的字节已经发送并且收到了确认,那么就将发送窗口向右滑动一定距离,直到左部第一个字节不是已发送并且已确认的状态。发送窗口一般是向右移动的,当然也可能不动(没有收到新的请求或对方的接收窗口变小),也可能收缩(但是TCP强烈不建议这么做,因为发送端在收到通知前可能已经发送了很多数据,将产生错误)。

接收窗口内的字节都允许被接收,窗口左边界之外是已发送确认并交付主机的序号,窗口右边界之外是不允许接收的序号(可能只是不在TCP的缓存中,但是可能存在于主机的其他缓存中)。接收窗口的滑动与发送窗口类似,接收窗口左部字节已经发送确认并交付主机,就向右滑动接收窗口。注意,接收窗口只会对窗口内最后一个按序到达的字节进行确认,例如接收窗口已经收到的字节为 {31, 34, 35},其中 {31} 按序到达,而 {34, 35} 就不是,因此只对字节 31 进行确认。发送方得到一个字节的确认之后,就知道这个字节之前的所有字节都已经被接收。

计算机网络常见面试题_第9张图片

 

(2)TCP是如何实现可靠传输的?

TCP使用超时重传实现可靠传输:如果一个已经发送的报文段在超时时间内没有收到确认,那么就重传这个报文段。一个报文段从发送到接收到确认所经过的时间成为往返时间RTT,其加权平均往返时间为RTTs,超时时间RTO应该略大于RTTs。

除此之外,1)应用数据被分割成TCP认为最适合发送的数据块;2)发送方TCP给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层;3)TCP首部有校验和字段,通过它可以检测数据在传输过程中有没有出错,如果收到段的校验和有差错,接收方将丢弃这个报文段、不确认收到该报文段;4)流量控制:TCP连接的双方都有固定大小的缓存空间,当接收方可以告知发送方自己剩余缓存空间的大小,以免发送方发送速率过快,接收方处理不过来;5)拥塞控制:当网络拥塞时,发送方放缓发送速率。

 

(3)TCP建立连接之后,拔掉网线还需要重连吗?

TCP具有KeepAlive机制,内核会为每一个连接都打开一个保活计时器,N个连接会打开N个保活计时器。这种机制是TCP协议层面的保活探测机制,系统内核完全替上层应用自动做好了,上层应用只需要处理数据收发、连接异常通知即可。而且内核层面计时器相比上层应用更加高效。当然,我们也可以在实现业务心跳,这样做的好处是可以完全掌管心跳,灵活可控,比如,实现每一个连接心跳周期的可根据需要减少或延长。

如果网线断开的时间比较短,在SO_KEEPALIVE设定的探测时间间隔内,并且两段在此期间没有任何针对此长连接的网络操作,则当连上网线后,此TCP连接可以自动恢复,继续进行正常的网络操作。

如果网线断开的时间很长,超出了SO_KEEPALIVE设定的探测时间间隔,或者两段在此期间有了任何针对此长连接的网络操作,则当连上网线时,会出现ETIMEDOUT或者ECONNRESET的错误,此时必须重新建立一个长连接才能进行网络操作。

HTTP协议也有Keep-Alive,不过其意图在于连接复用,同一个连接上串行方式传递请求-响应数据。而TCP的KeepAlive机制意图在于保活、心跳,检测连接错误。

关于TCP的KeepAlive机制可参考:https://blog.biezhi.me/2017/08/talk-tcp-keepalive.html 、https://tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/  、http://www.blogjava.net/yongboy/archive/2015/04/14/424413.html 、https://blog.biezhi.me/2017/08/talk-tcp-keepalive.html 、https://blog.csdn.net/effort1989/article/details/52753670 、https://www.zhihu.com/question/40602902 、 

关于ECONNRESET错误的案例可以参考:https://zhuanlan.zhihu.com/p/86953757,该案例展示了因为服务端先于客户端关闭TCP而客户端继续发出HTTP请求导致错误的一种情形。 

 

(4)TCP首部字段

计算机网络常见面试题_第10张图片

端口号:端口号的范围是1-65535,其中,0-1023位公认端口,它们的用途一般是固定的,像80端口总是用于HTTP通讯;1024-49151为注册端口,很多服务绑定于这些端口;49152-65535为私有端口,一般服务不应该绑定这些端口,不过也有例外。

端口号是一个逻辑的概念,并非物理上的实际存在的接口。有时可以采用端口重定向技术,例如将默认为80的HTTP端口重定向到8080端口,这样就隐藏了公认的默认端口,防止有人通过端口扫描对一个公认的默认端口进行攻击。

序号:用于对字节流进行编号,例如序号为301表示字节流的第一个字节的编号为301,如果携带的数据长度为100字节,那下一个报文段的序号应为401。

确认号:用于告知对方,期望收到的下一个报文段的序号。例如接收端正确收到发送端序号为301的一个报文段,携带的数据长度为100字节,那接收端期望下一个报文段的序号就是401,因此,接收端发送给发送端的确认报文段中确认号就为401。TCP数据部分的长度 = IP包总长度(IP数据包有总长度字段) - IP首部长度(20字节) - TCP首部长度(20字节)。

数据偏移:指的是数据部分距离报文段起始处的偏移量,实际上就是首部的长度。

ACK:确认,ACK = 1时确认号字段有效,否则无效。TCP规定,在建立连接后,所有传送的报文段都必须把ACK置为1。

SYN:同步,在建立连接时,用于同步序号。当SYN = 1,ACK = 0时表示这是一个连接请求报文,若对方同意建立连接,则连接响应报文中SYN = 1,ACK = 1。

FIN:终止,用于释放一个连接,当FIN = 1时表示此报文的发送方的数据已经发送完毕,并要求释放连接(关闭此发送方到对方的数据传输通道,关闭的只是单向通道)。

窗口:接收方用窗口值告知发送方自己的剩余的可接收数据的接收窗口缓存空间的大小

 

6、UDP概述

(1)UDP首部字段

计算机网络常见面试题_第11张图片

UDP的首部字段只有8个字节,包括源端口、目的端口、长度、校验和,它们各占2个字节。伪首部是为了计算校验和临时添加的。

1)在使用UDP协议发送数据时,伪首部是什么时候出现,又在什么时候消失的?

伪首部是一个虚拟的数据结构,其中的信息是从数据报所爱IP分组的分组头中提取的,既不向下传送也不向上递交,而仅仅是为了计算校验和。也就是说,伪首部只参与校验,不参与传输,所以不存在出现与消失的时机问题。

计算得到的校验和,既校验了UDP用户数据的源端口号、目的端口号、UDP用户数据报的数据部分,又校验了IP数据报的源IP地址、目的IP地址。

2)伪首部的作用是什么?

计算校验和,关于其的作用和校验和计算方法可以参考这个链接:https://blog.51cto.com/3layer/894104

(2)如何用UDP实现可靠通信?

要想基于UDP来实现可靠的面向连接的数据传输,就要实现类似于TCP的超时重传、有序接受、应答确认、滑动窗口、流量控制等机制,等于说要在应用层实现TCP的可靠数据传输机制,比如使用UDP数据包+序列号、UDP数据包+时间戳等方法。

至于为什么不直接用TCP,大概是因为TCP不够灵活,而基于UDP实现可靠通信可以理解为根据业务特性定制化的TCP,比如,很多游戏就是采用UDP实现可靠传输,而且又不会有TCP拥塞控制、慢启动等“缺点”。如果TCP允许个性化定制,在UDP和TCP之间动态过渡,就可以满足很多需求了。

各种业务场景下使用UDP实现可靠通信的案例:https://blog.csdn.net/kennyrose/article/details/7557917

http://www.52im.net/forum.php?mod=viewthread&tid=1293&highlight=udp

https://zhuanlan.zhihu.com/p/68466363

 

三、网络分层模型

 

1、OSI七层模型和TCP/IP五层模型的结构?各层的功能以及拥有的协议?

OSI七层模型:应用层 -> 表示层 -> 会话层 -> 传输层 -> 网络层 -> 数据链路层 -> 物理层

TCP/IP五层模型:应用层 -> 传输层 -> 网络层 -> 数据链路层 -> 物理层

(1)应用层

作用:应用层的主要任务是通过应用进程之间的交互来完成特定网络应用。

协议:应用层协议定义的是应用进程之间的通信和交互的规则。应用层协议有域名系统DNS、支持万维网应用的HTTP协议、支持电子邮件的SMTP协议。

数据:应用层之间交互的数据单元称为报文。

(2)传输层

作用:传输层的主要任务时负责向应用进程之间的通信提供通用(不针对某一个特定的网络应用,多种应用可以使用同一个传输层)的数据传输服务(应用进程利用该服务传输应用层报文)。由于一台主机可同时运行多个进程,因此传输层有复用和分用的功能,复用指的是多个应用层进程可以同时使用传输层的服务,分用指的是传输层把收到的信息分别交付给应用层中的相应进程。

协议:传输控制协议TCP、用户数据报协议UDP

数据:TCP产生报文段、UDP产生用户数据报

(3)网络层

作用:由于计算机网络中进行通信的两个主机之间可能经过很多个通信子网,网络层的主要任务是选择合适的网间路由和交换节点,确保数据及时传送。由于互联网使用的网络层协议是无连接的网际协议和许多路由选择协议,因此网络层也叫做网际层或IP层。

协议:IP协议

数据:将传输层的报文段或用户数据报封装成分组进行传输,这些分组也称为IP数据报,简称数据报

(4)数据链路层

作用:由于两个主机之间的数据传输总是在一段一段的链路上传送的,因此,需要使用专门的链路层协议来执行实际的两个节点之间的传输。在两个相邻节点之间传输数据时,数据链路层将网络层传下来的IP数据报封装成帧,在两个相邻节点之间的链路上传输帧,每一帧包括数据和必要的控制信息(如同步信息、地址信息、差错信息等)。接收数据时,接收端通过控制信息可以知道一个帧从哪个比特开始、到哪个比特结束,从而提取出数据部分,传给网络层。此外,接收端还可以通过控制信息检测所收到的帧有无差错,如果有差错,数据链路层就简单丢弃这个出差错的帧,防止继续传送下去浪费网络资源。此外,数据链路层除了检错还可以纠错,纠正数据在链路层传输时出现的差错,不过这样会使得链路层的协议更加复杂。

协议

数据:帧

(5)物理层

作用:物理层的主要任务是实现相邻节点之间比特流的透明传输(尽可能屏蔽掉具体传输介质和物理设备的差异),其目标是使得经过实际电路传送后的比特流没有发生变化(透明的意思也就是说,对于待传输的比特流来说,这个电路好像是看不见的)。

数据:在物理层上传输的数据单位是比特。

(6)小结

真正通信的并不是主机而是主机中的进程。

传输层只是提供一些传输服务,并不负责传输,真正负责传输的是下面几层。传输层提供了进程间的逻辑通信,传输层向高层用户屏蔽了下面网络层的核心细节,使得应用程序看起来像是在两个传输层实体之间有一条端到端的逻辑通信信道。

网络层只是负责把分组发送到目的主机。如果把分组看成一个人,则网络层的作用其实相当于一个人走到岔路口之后,选择一条合适的路径继续向前走。

数据链路层则是在网络层选好路径之后,控制在选定的链路上(两个节点之间)的传输,像差错控制之类的。

物理层实现的是一个数模转换和模数转换功能,将数字的比特流转换成模拟的电流信号,反之亦然。

计算机网络常见面试题_第12张图片

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

参考:

https://github.com/CyC2018/CS-Notes

https://github.com/Snailclimb/JavaGuide

https://zhuanlan.zhihu.com/p/76023663

https://blog.csdn.net/Bad_Sheep/article/details/6158676

https://blog.csdn.net/yusiguyuan/article/details/22825161

https://blog.csdn.net/qq_43824618/article/details/105450539

https://www.zhihu.com/question/424099890

https://blog.csdn.net/My_heart_/article/details/52601924

https://segmentfault.com/a/1190000006879700

 

你可能感兴趣的:(计算机网络,网络,session,cookie)