深度思考计算机网络面经

tcp拥塞控制和流量控制

下面这篇文章是我见过的讲解的最好的关于拥塞控制的文章:TCP拥塞控制,慢启动、拥塞避免、快重传以及快恢复

快重传和选择重传的区别

TCP(Transmission Control Protocol)协议中的“快重传”和“选择性重传”都是针对丢失数据包的恢复机制,但它们在何时触发重传以及如何处理丢失数据包方面有所不同。

  1. 快速重传(Fast Retransmit):快速重传机制通过检测连续三个相同的重复ACKs(Acknowledgement,即确认包)来判断一个段是否已丢失,而不用等待超时计时器的超时。在收到三个重复的ACK时,TCP会尽快重传丢失的数据段,而不需要等待超时。这样,可以更快地响应数据段的丢失,降低了网络拥塞的可能性,并且提高了数据传输的效率。

  2. 选择性重传(Selective Retransmission):选择性重传机制是对快速重传机制的一种改进,它可以更精细地控制哪些数据段需要重传。当接收端发现有数据段丢失时(接收到的数据段序号不连续),它会发送一个SACK(Selective Acknowledgement,即选择性确认)包,指定丢失的数据段序号,而不是最后一个成功接收的数据段的序号。这样,发送端只需要重传丢失的数据段,而不是所有未被确认的数据段。这样,选择性重传可以更有效地处理数据段的丢失,尤其是在网络条件差或数据丢失较多的情况下。

总的来说,快速重传和选择性重传都是TCP协议中应对数据包丢失的策略,但它们的侧重点不同。快速重传侧重于快速响应数据包的丢失,而选择性重传则更关注于准确地指定丢失的数据包以提高传输效率。

快重传对应的是GBN协议,而选择重传对应的是SR协议对吧?

在某种程度上,你的理解是正确的。GBN(Go-Back-N)和SR(Selective Repeat)协议是两种常见的基于滑动窗口的可靠数据传输协议,它们在处理数据包丢失时的策略和TCP的快重传以及选择性重传机制类似。GBN协议在发现丢包时会重传从丢包开始后面所有的包,类似于TCP的快速重传。而SR协议则会只重传丢失的包,这和TCP的选择性重传类似。

GBN协议和SR协议两者在TCP的拥塞控制中都有应用吗

是的,快重传和选择性重传在TCP的拥塞控制中都有应用。快重传通过更早地发现和重传丢失的数据包,可以避免不必要的超时等待,从而降低网络的拥塞程度。而选择性重传通过只重传丢失的数据包,可以减少不必要的数据包传输,也有利于降低网络拥塞。

在网络的拥塞控制上,GBN协议和SR哪一个表现更优秀

在网络的拥塞控制上,选择性重传一般被认为比快速重传更优秀。因为选择性重传只重传丢失的数据包,避免了因重传过多不必要的数据包而导致的额外网络负载。然而,实际上这两种机制并不是互斥的,在许多现代的TCP实现中,快重传和选择性重传会结合使用,以在不同情况下提供最优的网络性能。

GBN协议和SR协议在多个链路层应用和运输层应用的比较

GBN协议和SR协议不是数据链路层的协议吗,为什么TCP也使用了

GBN(Go-Back-N)协议和SR(Selective Repeat)协议是两种基于滑动窗口的可靠数据传输协议,最初是设计用于数据链路层的。但是,它们的基本原理和机制也可以被应用在更高层的协议中,比如传输层的TCP协议。在TCP协议中,也使用了类似滑动窗口的机制来实现可靠数据传输,并且在处理数据包丢失时,也采用了类似于GBN的快速重传和类似于SR的选择性重传的策略。

数据链路层不是也能保证可靠传输吗,为什么TCP层也要保证呢

数据链路层的确提供了一定的可靠传输功能,比如错误检测和纠正、数据包的重传等。但是,这些功能主要是为了应对数据链路层面的问题,比如物理介质的干扰和噪声等。当数据包在网络中传输时,可能会遇到各种各样的问题,比如路由器的故障、网络拥塞等,这些问题都可能导致数据包的丢失。而这些问题是数据链路层无法解决的,因此在传输层也需要有可靠传输的机制。同时,TCP还提供了一些数据链路层无法提供的功能,比如流量控制、拥塞控制等。这些都需要在传输层进行处理。

为什么数据链路层无法解决”路由器的故障、网络拥塞导致的丢包问题“,链路层不是也可以保证重传吗

数据链路层主要处理两个直接相连的网络节点之间的通信问题。它确实可以通过错误检测和重传来保证数据的正确传输,但这种保证只限于单个链路。如果一个数据包需要经过多个链路(即多个路由器)才能到达目的地,那么数据链路层就无法保证全程的可靠传输了。比如,一个路由器突然故障或者网络中某处发生拥塞,导致数据包丢失,这些问题是数据链路层无法感知和处理的。因此,我们需要在更高的层级,如传输层,实现端到端的可靠传输。

数据链路层,传输层和应用层都有可能发生重传,这三者的重传的原因有什么不同?

对于数据链路层、传输层和应用层可能发生的重传,它们的原因和目标是有所不同的:

  • 数据链路层的重传主要是为了应对单个链路中的传输错误,比如因为信号干扰、硬件故障等原因导致的数据包丢失或损坏。
  • 传输层的重传则主要是为了实现端到端的可靠传输,也就是说,即使在复杂的网络环境中(包含多个网络,多个链路),也要保证数据能从发送端正确无误地到达接收端。这包括应对网络中的路由器故障、网络拥塞等问题。
  • 应用层的重传则更侧重于应用的特定需求。比如,某些实时性要求很高的应用,可能会在数据包延迟到达时就选择重传,而不等到超时。又或者,一些要求数据完整性的应用,可能会在接收到的数据出现任何问题时就选择重传。

你举的这几个应用层重传的例子不够细化,举一个秒杀系统中可能存在的应用层重传问题

在一个秒杀系统中,应用层重传的场景可能会出现在订单创建阶段。假设用户成功地通过秒杀抢到了一个商品,并且已经开始创建订单的过程。在这个过程中,系统需要调用库存服务扣减库存,同时还可能需要调用用户服务检查用户的身份和支付能力等。这些服务调用都可能出现网络延迟或者服务暂时不可用的问题。

假设系统在调用库存服务时,没有在预期的时间内得到响应。在这种情况下,系统可能会选择进行应用层的重传,即再次发送扣减库存的请求。这是因为如果不这样做,用户可能会因为等待时间过长而感到不满,甚至可能会导致订单创建失败。但同时,系统也需要设计好重传策略,以防止过度重传导致的库存扣减错误(保持重传接口的幂等性)。

或者,如果系统在调用用户服务时,发现返回的用户信息存在问题,比如用户的支付能力低于商品的价格。这时,系统可能会选择重传用户服务的请求,以确认是否真的存在这个问题。这是因为如果不确认这个问题,可能会导致订单创建失败,从而让用户错失了本应获得的商品。

这些都是应用层重传的例子,它们都是根据应用的具体需求和特性来决定的。

输入一个网址的全过程

输入一个网址并访问该网址的全过程涉及到了多个网络协议和网络层次,其中包括ARP协议。下面是一个比较详细的过程:

  1. URL输入:在浏览器地址栏中输入URL(如:http://www.example.com)。

  2. DNS查询:浏览器通过DNS(Domain Name System)协议将www.example.com解析为对应的IP地址。这一过程可能涉及到本地DNS缓存、系统(如Windows的hosts文件)或者网络上的DNS服务器。

  3. ARP查询:如果目标IP地址不在本地网络中,数据包需要通过路由器或网关传送。这时,系统会通过ARP(Address Resolution Protocol)协议获取网关的MAC地址,因为在以太网层,数据的传输是基于MAC地址的。

  4. 建立TCP连接:浏览器向解析出的IP地址发起TCP(Transmission Control Protocol)连接,进行三次握手。

  5. HTTP请求:TCP连接建立后,浏览器就可以通过HTTP(HyperText Transfer Protocol)协议向服务器发送GET请求,请求访问www.example.com的网页内容。

  6. 服务器响应:服务器接收到HTTP请求后,会处理这个请求,然后通过TCP连接将响应数据(通常是HTML文件)返回给浏览器。

  7. 浏览器解析HTML:浏览器接收到HTML数据后,会对其进行解析,并请求HTML中引用的其他资源(如CSS、JavaScript、图片等)。这些资源的请求和接收过程与访问主页面的过程相同。

  8. 关闭TCP连接:页面和所有资源都加载完后,浏览器会关闭TCP连接。具体是立即关闭还是保持一段时间,取决于HTTP头部的"Connection"字段。

这个过程涵盖了从应用层(HTTP、DNS)到传输层(TCP)、网络层(IP)和链路层(ARP)的各种网络协议。不过请注意,实际过程可能会因为各种因素(如缓存、网络设备、协议版本等)而有所不同。

最终目的ip的mac地址一定能被主机所在局域网路由器找到吗

不一定。如果目标IP地址是在同一个局域网中,那么通过ARP协议,可以在局域网内找到这个IP地址对应的MAC地址。然而,如果目标IP地址不在同一个局域网中,那么我们无法直接找到该IP的MAC地址。

在这种情况下,通常的做法是,主机会将数据包发送到它的默认网关(通常是路由器)。它使用ARP找到默认网关的MAC地址,然后将数据包发送到那里。然后,网关或路由器将负责将数据包路由到正确的目标IP地址。在这个过程中,可能会经过多个中间路由器,每个路由器都可能需要进行ARP查询以找到下一个跳点的MAC地址。直到最后一跳,也就是目标IP所在的局域网,那里的路由器或网关会使用ARP找到目标IP的MAC地址,并将数据包发送到那里。

所以,主机本身不需要知道目标IP的MAC地址,除非目标IP在同一个局域网中。在大多数情况下,主机只需要知道其默认网关的MAC地址即可。

所以ARP协议的最终目的是找到下一跳的mac地址

是的,你的理解是正确的。ARP(地址解析协议)的主要目的是将网络层的IP地址映射到数据链路层的MAC地址。在实际的网络通信中,这主要用于确定下一跳的MAC地址。

如果目标IP地址在本地网络(即在同一子网)中,下一跳就是目标设备,ARP将用于查找目标设备的MAC地址。

如果目标IP地址不在本地网络中,那么数据包需要被路由到其他网络。在这种情况下,下一跳通常是设备的默认网关(通常是路由器)。ARP将用于查找默认网关的MAC地址。

在每一次转发过程中,路由器将根据它的路由表确定数据包的下一跳,然后使用ARP确定下一跳的MAC地址。这个过程将在每个路由点重复,直到数据包到达其目标网络。在目标网络中,最后一跳的路由器将使用ARP查找目标设备的MAC地址,并将数据包发送到该设备。所以,ARP协议的最终目的是找到下一跳的MAC地址,无论下一跳是目标设备还是路由器。

HTTP请求

get post之类外, 还有什么指令

在HTTP(超文本传输协议)中,有多种类型的请求方法,也被称为HTTP动词。最常见的包括GET和POST,但还有其他几种,如PUT, DELETE, HEAD, OPTIONS, PATCH, CONNECT等。

以下是这些请求方法的基本描述:

  • GET:用于请求指定的资源。GET方法应该只用于数据检索,并且不应该影响数据的状态。
  • POST:用于提交数据,通常用于表单提交。POST请求可能会导致新的资源的创建和/或已有资源的修改。
  • PUT:用于替换目标资源的所有当前表示。
  • DELETE:删除指定的资源。
  • HEAD:类似于GET方法,但服务器在响应中只返回HTTP头部,不返回实际的数据内容。
  • OPTIONS:用于获取目标资源支持的通信选项。
  • PATCH:用于对资源进行部分修改。
  • CONNECT:用于建立网络隧道,通常用于SSL隧道。

GET和POST的主要区别

GET和POST的主要区别包括以下几点:

  1. 数据在请求中的位置:GET方法通过URL传递数据,而POST方法通常在请求体中传递数据。
  2. 数据大小:由于浏览器和服务器对URL长度的限制,GET方法传递的数据量较小。POST方法由于其数据不放在URL中,理论上数据量可以非常大。
  3. 数据类型:GET只允许ASCII字符的数据。而POST没有限制,可以允许二进制数据。
  4. 安全性:由于GET请求的数据直接包含在URL中,这些数据可能会在浏览器历史或web服务器日志中留下记录,因此GET较POST来说安全性较低。
  5. 影响(主要区别):GET方法通常被认为是幂等的,意味着多次执行同一GET请求,服务器的状态是相同的。而POST方法会对服务器状态产生影响,可能会改变服务器的状态。
  6. tcp包数量::GET产生一个TCP数据包,浏览器会把http header和data一并发送出去,服务器响应200(返回数据); POST产生两个TCP数据包,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
    7.缓存: GET请求会被浏览器主动缓存,而POST不会,除非手动设置。

以上是GET和POST两种HTTP请求方法的主要区别,但在实际使用中,还需要根据应用的实际需求和情况来选择适当的请求方法。

**注意:**正因为它们有这样的区别,所以不应该且不能用get请求做数据的增删改这些有副作用的操作。因为get请求是幂等的,在网络不好的隧道中会尝试重试。如果用get请求增数据,会有重复操作的风险,而这种重复操作可能会导致副作用(浏览器和操作系统并不知道你会用get请求去做增操作)。

Get请求为什么是幂等的,后端也可以根据参数进行增删吧?

你是对的,从技术层面来说,服务器端确实可以根据GET请求的参数来做出修改数据的操作。然而,从设计原则和实践中来看,GET请求被设计为一个安全的方法,意味着它应该只被用来读取信息而不是修改信息。这种设计是基于统一的网络接口和预期的行为,这样可以使得软件开发者、用户和各种网络设备(如缓存服务器)对HTTP请求有一致的预期。

幂等性是HTTP方法的一个重要特性,定义为无论一个方法被执行多少次,服务器的状态都应该保持相同。对于GET请求,这通常意味着多次GET同一URL,服务器的状态并不会因此发生改变,而返回的结果应该也是相同的(忽略缓存和外部数据源的影响)。

在实际操作中,如果服务器端选择忽视这一原则,并在收到GET请求时修改数据,那么可能会导致一些不预期的行为。例如,网络爬虫通常会认为GET请求是安全的,因此可能会频繁地对一个URL发起GET请求,如果每次GET请求都修改服务器状态,那么可能会导致数据被意外地改动。

因此,尽管从技术角度来说GET请求可以用来修改数据,但在实际使用中,我们应该遵守HTTP方法的设计原则,使用GET请求来获取数据,而使用POST或其他类型的请求来修改数据。

如果GET请求来修改数据,还能保证幂等性吗

从严格的理论角度来看,如果GET请求用于修改数据,那么它将不能保证幂等性。因为幂等性的定义是无论你对一个系统执行同一个操作多少次,结果都是一样的,也就是说不会因为重复执行操作而改变系统的状态。

例如,如果你将GET请求用于删除一个用户,例如通过 GET /deleteUser?id=123 这样的请求,那么在第一次请求后,用户123就被删除了。如果你再次发送同样的GET请求,由于用户123已经不存在了,所以第二次的请求和第一次的请求效果就不一样了,这就破坏了幂等性。

从实践角度来看,使用GET请求来修改数据是一种不好的设计实践,因为它违反了HTTP规范和语义,可能会导致不可预见的副作用。例如,搜索引擎爬虫或者其他自动化工具在访问网页时可能会发送GET请求,如果GET请求可以修改数据,那么这可能会导致数据被意外修改。因此,我们通常推荐使用POST、PUT、DELETE等HTTP方法来进行数据的修改操作,而将GET方法保留用于数据的获取。

因为get规定的操作幂等性,只要是查询操作,所以没有机制来防止重复请求的吗?

GET请求是幂等的,这意味着对同一URL的多个请求应产生相同的结果。它主要用于从服务器检索数据。由于GET请求的幂等性,HTTP/1.1协议规定,服务器无法阻止这种重复的请求,因为它们都应产生相同的结果。但在实际的开发中,如果我们需要对GET请求进行限流或者其他类型的控制,我们可以在应用层面进行设计和处理。

POST不幂等,那是不是存在一种机制防止重复的post请求?

HTTP协议没有内建的机制来防止重复的POST请求,是因为HTTP被设计为一个无状态的协议,它不保留之前发生的请求或响应的任何信息。这使得HTTP可以更简单、更可扩展,并且可以应对各种网络环境。因此,HTTP协议本身并不关注是否有重复的请求,这是交由应用层去解决的问题。

但是TCP本身能防止重复的数据报文段到达接收方啊,为什么应用层还存在重复的post请求?

TCP可以确保数据报文段的顺序和完整性,避免数据丢失或重复。但在HTTP层面,重复的POST请求并不仅仅是指网络层面的重复数据。它也可以是由于用户多次点击按钮,或者浏览器或网络问题导致的请求重试等。这些情况下,虽然每个POST请求在TCP层面都是唯一的,但在HTTP和应用层面,它们被视为重复的请求。

这和raft状态机保持get,put和putAppend操作幂等性有什么区别

Raft是一种用于管理复制日志的共识算法,它的目标是确保系统的强一致性。在Raft中,GET, PUT和PUT_APPEND操作的幂等性是由算法保证的。这意味着,无论这些操作被执行多少次,结果总是一样的。这与HTTP的GET和POST操作有所不同,因为HTTP的POST操作是非幂等的,相同的POST请求可能会产生不同的结果。对于Raft和HTTP来说,保证操作的幂等性是为了处理网络不可靠性带来的问题,但它们的实现机制和应用场景有所不同。

用户多次点击导致的多个POST请求时,除了前端在页面禁止用户重复提交表单,后端有什么措施可以真正禁止吗?

一种常见的做法是在表单中添加一个隐藏的唯一令牌。服务器生成这个令牌并将其与用户的会话关联起来。当用户提交表单时,令牌将一同发送给服务器。服务器会检查令牌是否存在且未被使用。如果令牌有效,服务器将处理表单提交,否则将拒绝重复的提交。

另一种做法是在数据库中记录每个用户的每个操作,并检查新的操作是否重复。例如,如果用户正在试图提交订单,服务器可以检查是否已经存在一个相同的未处理订单。

在raft中,因为网络不可靠,所以发送端因为超时重传会重复发送一些HTTP请求,对于这种就需要防止幂等性对吗?

是的,对于在网络不可靠的情况下可能重复发送的请求,我们需要确保请求的幂等性。在Raft协议中,为了实现这一目标,一个重要的设计原则是确保操作的幂等性,这意味着无论一个操作被执行多少次,结果总是一样的。因此,如果由于网络不可靠导致的请求重发,由于操作的幂等性,不会对系统的最终状态产生影响。例如,对于同一条log entry的多次复制,由于复制操作是幂等的,只要log entry在任何一个follower上写入成功,重复的复制操作都不会改变系统的状态。

防止用户重复提交表单:如果使用令牌的方式,具体的产生和携带流程给我讲解一下

使用令牌防止用户重复提交表单的具体流程通常如下:

  • 当用户访问表单页面时,服务器生成一个唯一的令牌。
  • 服务器将这个令牌保存在用户的会话中,并将令牌作为隐藏字段添加到表单中。
  • 用户填写表单并提交时,令牌将一同发送到服务器。
  • 服务器收到表单提交请求后,检查提交的令牌与会话中存储的令牌是否一致。如果一致,处理这个请求。然后,服务器将该令牌标记为已使用,对于使用这个令牌的后续请求将会被拒绝。

查询是否存在一个相同的未处理订单,应该根据用户id+商品id在订单表中查询吧,

查询是否存在一个相同的未处理订单,具体的查询条件可能取决于你的业务需求。通常,我们会根据用户ID和商品ID在订单表中查询。然而,如果用户在短时间内可能会购买同一商品的多份订单,可能还需要考虑其他因素,如订单的状态(未支付、已支付、已完成等)和订单创建的时间等。

对于下单场景,存在多种情况,比如短时间内多次点击按钮导致重复下单,另一种是用户的确想购买多次,针对前者我们应该防止,对于后者我们应该允许发生,如何在秒杀和一般购买场景下分别解决这两种场景?

对于区分用户重复点击和用户真正想购买多次的场景,一个可能的解决方案是:

对于防止用户重复点击,可以在前端实现禁用提交按钮直到服务器响应,或者在后端使用上述提到的令牌机制,限制在短时间内对同一商品的重复订单。

对于用户真正想购买多次的情况,可以设置一个稍长的时间间隔(比如5分钟或更长),在这个时间间隔内,同一个用户对同一个商品的订单将被视为重复订单。这个时间间隔应当长到用户不大可能无意识地多次点击,但短到不会妨碍用户连续购买。同时,用户也可以在购买时直接选择购买多份,避免需要多次下单。

HTTP2和1.1的区别

HTTP2的Multiplexing

HTTP2 Multiplexing是什么,有什么作用,机制是什么

在HTTP/1.1中,每个HTTP请求需要一个独立的TCP连接,这使得同时发送多个请求需要开启多个TCP连接。但在HTTP/2中,引入了多路复用(Multiplexing)技术,允许在单个TCP连接上同时发送多个HTTP请求和接收响应。

HTTP中的流水线和Multiplexing,Multiplexing和持久连接的非流水线技术的关系

流水线和Multiplexing是HTTP协议中两种不同的技术,它们都旨在提高网络传输的效率。

流水线(Pipelining):在HTTP/1.1中引入,允许在一个持久连接中,客户端可以连续发送多个请求,而无需等待每个响应。但是,HTTP/1.1规定响应必须按照请求的顺序返回,这就引发了“队头阻塞”问题,即如果一个请求的处理需要很长时间,那么后续的响应也会被阻塞。

Multiplexing(多路复用):在HTTP/2中引入,允许在一个持久连接中,客户端和服务器可以同时处理多个请求和响应。Multiplexing通过将每个请求和响应分割为多个帧,这些帧可以在一个连接中混合发送,并在接收端进行重新组装。由于没有了队头阻塞问题,Multiplexing的效率更高。

为什么允许浏览器同服务端建立多个tcp连接?不是有流水线技术吗?

虽然HTTP/1.1中的流水线技术和HTTP/2中的Multiplexing技术都可以在一个TCP连接中处理多个HTTP请求,但是由于队头阻塞问题,流水线技术在实践中使用得并不多。因此,HTTP/1.1的客户端通常会为同一个服务器建立多个TCP连接,以并行处理多个HTTP请求。而在HTTP/2中,由于引入了Multiplexing技术,一个TCP连接就可以并行处理多个请求,因此一般不再需要建立多个连接。

如果允许建立多个tcp连接,接收端如何区分和按照规则重组同时接收的多个报文段?

TCP协议保证了每个连接的数据的有序性和完整性。在TCP协议中,每个数据段都有一个序号,接收端可以根据这个序号来重新组装数据。所以,即使有多个TCP连接,接收端也可以正确地处理每个连接的数据。这是由于每个TCP连接都有独立的序列号空间和确认机制,因此,尽管这些连接可能同时存在,但它们是完全独立的。

1 问:每个TCP连接都有独立的序列号空间和确认机制来保证即使建立多个TCP连接,接收方也能正确重组,讲讲这种机制?

在TCP协议中,每个TCP连接都被定义为一个四元组:源IP地址、源端口、目的IP地址、目的端口。这个四元组唯一地标识了一个TCP连接。每个TCP连接都有自己独立的序列号空间,这是由TCP协议保证的。序列号用于标识在TCP连接中发送的数据字节的顺序。

当建立一个新的TCP连接时,发送方和接收方都会在握手过程中交换它们的初始序列号(ISN)。之后,发送方发送的每一个字节都会有一个序列号,这个序列号就是该字节的ISN加上它在发送数据流中的偏移量。接收方可以根据这个序列号来判断接收的数据字节的顺序,以及是否有数据丢失。

此外,TCP还使用确认机制来确认数据的接收。当接收方接收到数据后,它会发送一个确认(ACK),确认号是接收方期望接收的下一个字节的序列号。如果发送方没有收到接收方的确认,它会重新发送数据。

所以,通过独立的序列号空间和确认机制,即使有多个TCP连接,接收方也能正确地接收和重组每个连接的数据。

2 建立多个TCP连接就会占用多个端口对吗?

是的,每个新的TCP连接都需要一个新的端口。但需要注意的是,通常情况下,客户端(也就是发起连接的一方)会使用一个新的端口,而服务器端(接收连接的一方)通常会使用一个固定的、已知的端口(例如HTTP的默认端口是80,HTTPS的默认端口是443)。操作系统会为客户端自动选择一个未被使用的临时端口。

3 这里的TCP四元组源IP地址、源端口、目的IP地址、目的端口唯一标识了每一个TCP序列号的空间对不对?

对的,TCP四元组(源IP地址、源端口、目的IP地址、目的端口)确实唯一标识了一个TCP连接。序列号是在每个TCP连接内部使用的,用于保证连接中数据的正确顺序和完整性。这意味着每个TCP连接都有自己独立的序列号空间,不会和其他TCP连接冲突。这是因为每个TCP连接都是独立的,其状态(包括序列号)不会影响其他连接。

4 所以即使建立了多个TCP连接,目的端口依然不变,但是变化的是源端口,这样也唯一标识了命名空间?

是的,你的理解是正确的。即使多个TCP连接的目的端口(通常是服务器端的端口)相同,只要源端口(通常是客户端的端口)或源IP地址有所不同,这就足以在网络层面唯一标识一个TCP连接。这就是为什么我们可以同时从同一台设备(同一IP)打开多个连接到同一服务器的同一端口(比如浏览器的多个标签页连接到同一网站)。

5 在“所以即使建立了多个TCP连接,目的端口依然不变,但是变化的是源端口,这样也唯一标识了命名空间” 成立的条件下,目的端口都相同,所以就会发生复用和分用对吧?

对的,你的理解是准确的。我们称之为复用和分用是因为服务器端的同一端口能够服务于来自不同客户端的多个连接(复用),同时也能够根据每个连接的唯一标识(源IP和源端口)将接收到的数据正确地传送给对应的连接(分用)。

复用和分用

复用(multiplexing):指的是在网络发送端,较高层协议可以通过同一个较低层的服务接口发送数据到不同的接收端。例如,你的计算机(作为客户端)可以通过同一个网络层接口(即同一个IP地址和端口)发送数据到服务器的不同端口,或者发送到不同的服务器。这个过程我们称之为复用。

分用(demultiplexing):相应的,在网络接收端,较低层协议可以将接收到的数据按照一定的规则(比如目标IP和端口)分发给较高层的不同服务接口。例如,服务器可以将收到的数据根据数据的源IP和源端口信息分发到不同的应用程序。这个过程我们称之为分用。

下面这个是详细地址: 《计算机网络》知识总结-3.复用和分用

详细讲讲HTTP/2的Multiplexing实现机制

HTTP/2的Multiplexing实现机制:在HTTP/2中,所有通信都在一个TCP连接上完成,这个连接可以承载任意数量的双向数据流。每个数据流都有一个唯一的整数ID。数据流的请求和响应都是由HTTP帧组成的,这些帧可以在TCP连接中交错发送,然后在接收端根据数据流ID重新组装。

更具体地,HTTP/2定义了以下几种类型的帧:HEADERS和DATA用于请求和响应的元数据和主体;SETTINGS, PING, and GOAWAY等用于连接管理;PUSH_PROMISE用于服务器推送等。

由于HTTP/2的帧可以在一个TCP连接中交错发送,因此可以解决HTTP/1.x的队头阻塞问题,并使得连接的利用率更高。

这里涉及到的“帧”是指数据链路层的帧吗?

HTTP/2中的"帧"是在应用层的概念,它不是数据链路层的帧。在HTTP/2中,一个"帧"代表了HTTP/2通信中的最小单位,每一个帧包括帧头和帧体,其中帧头包含了该帧的类型、标志、长度、以及数据流的标识符。

这里的Multiplexing和TCP层的I/O多路复用是同一个概念吗?

HTTP/2的Multiplexing和TCP层的I/O多路复用不是同一个概念。HTTP/2的Multiplexing是指在一个TCP连接中可以并行处理多个请求和响应。而TCP层的I/O多路复用是指在底层操作系统中,可以使用单个线程来同时监控和操作多个I/O流,如select、poll、epoll等。

这里的Multiplexing 和linux的epoll,select等多路复用机制有什么区别?

HTTP/2的Multiplexing和Linux的epoll、select等多路复用机制的主要区别在于他们工作的层次不同:

HTTP/2的Multiplexing工作在应用层,它是HTTP/2协议的一部分,主要用于在一个TCP连接中并行处理多个HTTP请求和响应。

epoll、select等工作在操作系统层,它们是操作系统提供的接口,主要用于在一个线程中同时处理多个网络连接或其他I/O操作。

另外,epoll、select等多路复用机制是事件驱动的,当某个I/O流就绪(比如有数据可读)时,会触发相应的事件。而HTTP/2的Multiplexing则是数据驱动的,当有新的帧发送到TCP连接时,会立即处理这个帧。

这里HTTP的Multiplexing和TCP层的I/O多路复用应该有类似的原理吧?

HTTP/2的Multiplexing和TCP层的I/O多路复用的核心概念都是通过单一的连接或资源处理多个数据流或操作,所以在这个意义上,它们的原理是类似的。但是,如我在上一个回答中所述,它们工作的层次和具体的机制是不同的。

Multiplexing通过将每个请求和响应分割为多个帧,这些帧可以在一个连接中混合发送,可以理解为A请求的数据帧和B请求的一些数据帧混合在一个TCP报文段中然后发送给接收方,接收方的应用层根据分隔符,长度,套接字等字段的方式进行重组吗?

大致上你的理解是正确的,但细节上需要一些调整。在HTTP/2中,一个请求或响应的帧不会混合在一个TCP报文段中,而是作为独立的帧在TCP连接中发送。每个帧的头部都有一个数据流ID,这个ID用于指示这个帧属于哪个请求或响应。接收方的应用层可以根据这个数据流ID来将接收到的帧重新组装成完整的请求或响应。因此,不是根据分隔符、长度、套接字等字段来进行重组,而是根据每个帧的数据流ID来进行重组。

HTTPS和HTTP

HTTPS的交互流程

大概的交互流程:

是的,HTTPS基于HTTP协议,但是在HTTP和TCP之间增加了一个SSL/TLS的安全层。这个安全层为HTTP协议提供了数据加密服务,以保护数据在传输过程中不会被窃取或篡改,同时还可以进行服务器身份验证,以保护用户不会被引向假冒的服务器。

在实际使用中,HTTPS协议的工作流程大致可以分为两步:

  1. 握手阶段:在客户端和服务器之间建立SSL/TLS会话。在这个过程中,会进行服务器身份验证(通过服务器的SSL/TLS证书),同时双方还会协商出一套加密参数(例如使用哪种加密算法,密钥是什么等)。这个会话一旦建立,就可以提供加密服务。

  2. 数据传输阶段:客户端和服务器使用HTTP协议进行数据的传输,但是在数据发送出去之前,会先用握手阶段协商出的加密参数对数据进行加密,接收方在接收到数据后再进行解密。

所以,可以说HTTPS是基于HTTP的,但是增加了数据加密和服务器身份验证的功能,从而提供了更高的安全性。

更详细的交互可以参考下面:HTTPS的交互流程

针对SSL层的报文重放攻击如何处理?

上述操作看似是实现了对安全通信的三个基本需求,但是其对整个会话过程中报文流的数据完整性的保障并未达到天衣无缝,虽然单个记录的报文完整性可以由 MAC 保障,但是若是入侵者恶意调换两个 SSL 记录的顺序,或者故意多次重放同一个 SSL 记录多次,这样会导致接收方收到的最终报文不正确,这也就是 “报文重放攻击”。

报文重放攻击时指针对ssl层的嘛?因为tcp层次存在一个序号和确认号字段,能过滤掉重复的tcp报文段,但是过滤不掉tcp序号不同,但是ssl证书重放的tcp报文段对不对

是的,你理解得正确。报文重放攻击是对应用层,特别是那些使用加密和认证机制(例如SSL或TLS)的协议来说的。由于SSL/TLS在TCP层之上,它们通常不会处理TCP层面的问题,如数据重传或者丢包等,这些问题通常由TCP自身处理。因此,SSL/TLS需要处理一些TCP无法处理的安全问题,其中包括报文重放攻击。

在TCP层面,序列号和确认号确实可以过滤掉重复的TCP段,也能在一定程度上防止数据重排。然而,这并不能防止在SSL/TLS层面上的报文重放攻击。为什么呢?因为攻击者可能截取并存储一个完整的SSL/TLS会话,然后在稍后的时间里,再重放这个会话。尽管这些报文在TCP层面看起来都是新的(因为它们具有新的TCP序列号),但在SSL/TLS层面,它们其实是旧的报文,因此可能导致报文重放攻击。
因此,SSL/TLS必须在协议层面实现一些防御措施来防止这种攻击,例如通过在每个记录中包含一个隐式的序列号,并在计算MAC时考虑这个序列号,以此来确保报文的顺序和完整性。

业界通用的解决方案是什么样的呢?

业界的通用做法是在协议设计时考虑这种攻击场景,然后提供相应的保护措施。例如,SSL/TLS协议通过在MAC计算中引入序列号(即使这个序列号在发送的报文中并不可见,也就是"隐式"的)来防止重放攻击。除此之外,对于某些关键操作(例如支付操作),业务系统自己也会设计一些防重放机制,如在请求中包含一个时间戳,或者一个只能使用一次的随机数(nonce)等。

讲讲使用序列号的方式来防重放攻击的具体C/S交互流程

具体的C/S交互流程可能会因为具体的协议和应用场景而有所不同。但是对于SSL/TLS协议来说,它在握手阶段就会建立起双方共享的密钥,然后双方就可以开始安全地交换数据了。在这个过程中,为了防止重放攻击,每一侧的发送端会为它发送的每一条记录维护一个序列号,并在计算MAC值时使用这个序列号。当接收端收到一条记录后,它会用同样的方法来计算MAC值,如果计算出的MAC值与记录中的MAC值匹配,那么这条记录就会被接受。否则,如果MAC值不匹配,那么这条记录就会被拒绝,因为它可能是一个重放的记录。

重放会导致这个MAC不匹配,为什么

在SSL/TLS中,每次发送一条新的记录,发送端都会自增序列号(这个特性很重要,其实跟TCP的去冲机制很类似)。这个序列号被包含在了MAC(消息认证码)的计算过程中。MAC是通过将共享密钥、序列号、消息内容等数据进行特定算法运算得到的。这个MAC会被一同发送到接收端。

接收端在收到消息后,会使用同样的密钥和它自己维护的序列号进行同样的算法运算,得到一个新的MAC。然后接收端会比较这个新计算出的MAC和接收到的MAC是否一致。

如果发送端的消息被恶意重放,那么重放的消息中的MAC是在原发送时计算的,当时的序列号已经过时。而接收端在收到重放消息后,会使用当前的(已经增加的)序列号进行MAC计算,得到的MAC值和接收到的消息中的MAC是不一致的,因此接收端能够识别出这是一个重放的消息,并拒绝接收。

也就是说,序列号的自增机制和序列号在MAC计算中的使用,联合起来防止了重放攻击,这也是为什么重放会导致MAC不匹配的原因。

使用HTTPS通信,每次接收端收到一个请求都会对SSL的有效性进行校验嘛,校验过程中使用到了MAC的验证机制嘛,然后可以顺带去重?

使用HTTPS通信时,接收端会对每个SSL/TLS记录进行完整性和真实性的校验,这个过程中会使用到MAC。在每个记录接收和发送的过程中,都会维护一个序列号,这个序列号将被包含在MAC的计算过程中,所以通过验证MAC值的合法性,可以实现对重放攻击的防护。

MAC的加密、解密流程说一下,是不是使用对称密钥和非对称密钥的情况下,MAC的生成和校验流程不一样

MAC (Message Authentication Code) 是使用共享密钥和消息内容计算得出的一个值。其主要作用是用来验证消息的完整性和真实性,它不涉及到数据加密的过程。在SSL/TLS通信中,MAC的使用并不受对称加密还是非对称加密的影响,生成和验证的流程是一样的。

  • 在生成MAC时,首先会有一个预共享的密钥,这个密钥在通信双方之间是已知的。然后会将消息内容(包括序列号、消息长度等信息)和这个预共享密钥一起输入到一个特定的哈希函数(如HMAC-SHA256),输出的哈希值就是MAC。

  • 在验证MAC时,接收方将同样的预共享密钥和接收到的消息内容输入到同样的哈希函数中,计算得到一个新的MAC。然后比较这个新计算得到的MAC和接收到的MAC是否一致。如果一致,说明消息是由预期的发送方发送的,且在传输过程中没有被修改。如果不一致,说明消息可能被篡改,或者不是由预期的发送方发送的。

需要注意的是,MAC机制能够保证消息的完整性和真实性,但它不能保证消息的机密性,也就是说,消息本身并没有被加密,如果要保证消息的机密性,还需要其他的加密技术,如对称加密或非对称加密。

在请求中包含一个时间戳,为什么能防止ssl防重放攻击呢,是因为可以根据时间戳过滤掉太久远的https请求吗?

时间戳通常用来防止重放攻击的一种方法。服务端在接收到请求后,会检查请求中的时间戳是否在一个合理的时间窗口内(例如,过去的5分钟)。如果请求的时间戳过旧,服务器就可以认为这是一个重放的请求并将其拒绝。这就需要客户端和服务器的系统时间保持一致,或者至少要相差不大。

使用“一个只能使用一次的随机数”策略,是不是得要求双方存储这个随机数并且标记是否过期?

对于“一个只能使用一次的随机数”策略,通常需要服务端维护一份列表,记录所有的随机数以及他们是否被使用过。当服务端接收到一个请求,它会检查这个随机数是否在列表中,如果不在,说明这是一个新的请求,接受处理。如果在列表中且未使用,同样接受处理,并标记为已使用。如果在列表中且已被使用,那么拒绝这个请求。

MAC和JWT的关系,JWT会用到MAC嘛

MAC的全称Message Authentication Code,关于JWT可以参考这篇文章:想全面理解JWT?一文足矣
JWT (JSON Web Token) 和 MAC 的关系是,JWT 的签名部分可以使用 HMAC(一种基于密钥的哈希算法,是 MAC 的一种)生成。这种签名可以保证 JWT 的完整性和验证消息的发出者。

网站上输入一个URL涉及到的协议

过程

dns+arp+ip+tcp+http+ssl+websocket

一定得用到dns协议吗

不一定,如果url是直接使用ip+端口号访问则无语dns,如果只有域名则需要dns协议解析到dns协议

mac和ip的不同之处

MAC地址:物理地址,用于网络设备之间在同一局域网内进行通信。它是全球唯一的,由网络设备制造商在生产时分配,通常硬编码在网络接口卡(NIC)硬件中。
IP地址:逻辑地址,用于在网络上唯一标识一个网络接口。IP地址可能是静态分配的,也可能是动态从DHCP服务器上获取的。同一个网络设备在不同的网络环境下可能会有不同的IP地址。

arp是一种什么报文呢,用什么实现的呢,知道吗

ARP (Address Resolution Protocol) 是一种解析协议,可以将IP地址解析为对应的MAC地址。当一个设备需要向网络上的另一个设备发送数据时,它会首先使用ARP协议找到目标设备的MAC地址。ARP请求和回应都是封装在以太网帧中进行发送的。

到了主机之后,我怎么知道你要处理的是https还是http

这通常是通过所使用的端口来区分的。默认情况下,HTTP使用的是80端口,HTTPS使用的是443端口。当然,这些端口是可以配置的,不一定非要使用默认端口。(我答成了https的建立过程去了)
https不是建立在http之上吗,http的端口是80,打算https的是443,建立起http后还可以更改端口号吗?
HTTPS确实是建立在HTTP之上的,但它们使用的端口号是不同的。HTTP默认的端口号是80,HTTPS默认的端口号是443。这是由于HTTP和HTTPS实际上是两种不同的协议,尽管它们的内容和格式非常相似。当我们说将HTTP升级为HTTPS时,实际上是指在HTTP的基础上增加了SSL/TLS的加密层,从而使得数据传输更加安全。至于能否在建立起HTTP连接后更改端口号,一般来说,这是不可以的。端口号是在TCP连接建立时确定的,一旦TCP连接建立,端口号就不能改变。如果需要改变端口号,就必须断开现有的TCP连接,然后重新建立新的TCP连接。

建立ssl的第一个请求是由客户端发起还是服务端发起的呢?

在SSL/TLS协议中,连接的建立是由客户端发起的。客户端会首先发送一个“ClientHello”消息给服务器,表示它希望建立一个SSL/TLS连接。然后服务器会回应一个“ServerHello”消息,以及服务器的证书和“ServerHelloDone”消息。之后的握手过程中还会涉及到密钥交换和握手结束等步骤。
为什么是客户端发起的呢,因为客户端知道一开始就得使用https协议吗?
通常情况下,客户端是知道是否需要使用HTTPS的。比如当你在浏览器中输入一个URL时,你会指定是使用http://还是https://。如果你指定的是https://,那么浏览器就知道需要使用HTTPS,从而在建立TCP连接后,立即开始SSL/TLS握手过程。这个握手过程是由客户端发起的,因为在SSL/TLS协议中,客户端负责提供加密参数的选择,并开始握手过程。

数字证书里面有什么呢?

数字证书通常包含以下信息:
证书所有者的公开密钥
证书所有者的信息(包括名称、电子邮件地址、使用证书的权限等)
发行证书的证书颁发机构(CA)的信息
证书的有效期
证书颁发机构对上述信息的数字签名

客户端拿到证书怎么验证是否有效呢?

验证证书是否是上级CA 签发的, 在验证证书的时候,浏览器会调用系统的证书管理器接口对证书路径中的所有证书一级一级的进行验证,只有路径中所有的证书都是受信的,整个验证的结果才是受信。

客户端在收到服务器的证书后,会做以下检查来验证证书的有效性:
验证证书的签名:客户端会使用证书颁发机构的公钥来验证证书的签名,以此来确认证书的内容没有被篡改。
验证证书的有效期:证书都有一个有效期,如果当前日期不在证书的有效期内,那么证书就是无效的。
验证证书的颁发机构:客户端会检查证书的颁发机构是否是信任的,这通常是通过检查操作系统或浏览器中的信任的CA列表来完成的。

验证证书的签名:客户端会使用证书颁发机构的公钥来验证证书的签名,以此来确认证书的内容没有被篡改。你能看开讲讲其中的流程吗?
对于数字证书的签名验证过程,以下是一种可能的简化描述:
客户端收到服务器的数字证书后,首先从证书中获取证书颁发机构(CA)的公钥。
客户端使用CA的公钥来解密证书中的数字签名,得到一个摘要值。
客户端同时也会对证书中的除了数字签名之外的所有内容进行哈希计算,得到另一个摘要值。
客户端将这两个摘要值进行比较,如果它们相同,那么就说明证书的内容没有被篡改过,证书是有效的。如果它们不同,那么就说明证书的内容可能被篡改过,证书是无效的。

这个过程中的关键是,只有真正的CA才能生成一个能够被它的公钥正确解密的数字签名,因此通过这种方式可以验证证书是否是由真正的CA颁发的,以及证书的内容是否被篡改过。

udp有哪些优点,分别对应哪些场景呢?

UDP (User Datagram Protocol) 是一种无连接的协议,它的主要优点包括:
简单:UDP不需要建立和断开连接,也不需要进行复杂的错误检查和恢复,这使得UDP的实现相对简单。
高效:由于UDP不需要进行连接管理和错误恢复,因此它比TCP更加高效。
UDP常常用于那些不需要可靠传输,或者可以在应用层处理错误恢复的场景。例如:视频流传输、实时游戏、VoIP等。

udp包能装多少数据呢?

UDP数据报的大小是有限的。它的头部占用8字节,包括源端口、目标端口、长度和校验和。UDP数据报的长度字段是16位的,因此UDP数据报的最大大小是2^16 - 1 = 65535字节。减去8字节的头部,以及IP头部的最小大小(20字节),剩下的最大有效载荷是65507字节。

转发的时候真正的能一次性将支持的最大字节数的包转出去吗
实际上,虽然理论上UDP数据报的最大大小是65535字节,但在实际网络中,往往受到各种限制。例如,IP协议规定,如果一个数据包的大小超过MTU(最大传输单元),那么这个数据包就需要被分片,然后在接收端再重新组装。一般来说,以太网的MTU是1500字节,因此在以太网环境下,如果一个UDP数据报的大小超过了这个值,就可能需要被分片。但是,UDP是一个无连接的协议,它没有像TCP那样的重传机制,因此如果一个UDP数据报的某个分片丢失了,那么整个数据报都会被丢弃。所以,在实际应用中,我们通常会尽量避免发送过大的UDP数据报,以避免分片和可能的数据丢失。

是的,为了避免UDP数据报过大导致的分片和可能的数据丢失,一般来说,应用层需要负责控制每个UDP数据报的大小。这是因为UDP本身是一个简单的、无连接的协议,它并没有提供任何关于拥塞控制、流量控制或者错误恢复的机制。因此,对于这些问题,通常需要在应用层进行处理。

在一些需要实时数据传输的应用中,比如视频会议或者在线游戏,UDP是一个非常常用的协议。在这些应用中,通常会通过一些策略来避免发送过大的UDP数据报。比如,可以通过调整视频编码的参数来控制每个视频帧的大小,或者只在每个UDP数据报中包含一部分的视频帧,以保证每个UDP数据报的大小不会超过MTU。当然,这样做可能会增加编程的复杂性,因为需要处理数据的分片和组装,但是通过这种方式可以避免网络层的数据报文分片,从而提高数据传输的效率和稳定性。

http如何跨域?

HTTP如何跨域:在HTTP中,跨域是由于浏览器的同源策略限制。但有一些常用的方式可以进行跨域:

  • JSONP(JSON with Padding):只能进行GET请求。
  • CORS(跨域资源共享):服务器设置响应头Access-Control-Allow-Origin允许来源进行访问,还可以通过Access-Control-Allow-Methods,Access-Control-Allow-Headers等设置允许的方法和头部。
  • 使用代理:例如设置Nginx进行反向代理(此时代理服务器必须和客户机同源,然后再由代理服务器设置完成跨域请求),或者在Node.js中设置HTTP代理。
  • 使用Websocket进行通信。
  • 使用服务器间通信或者存储共享等方式绕过浏览器。

websocket

websocket和http的关系

  1. WebSocket 和 HTTP 的关系:

    WebSocket 和 HTTP 都是通信协议,它们都基于 TCP/IP 协议。WebSocket 是独立的、创建在 TCP 上的协议。HTTP 和 WebSocket 都可以使用 URL Scheme 来定义地址,HTTP 使用 http 或 https,而 WebSocket 使用 ws 或 wss(对应于 HTTP 和 HTTPS 的加密连接)。

websocket是建立在http之上的吗

  1. WebSocket 是否建立在 HTTP 之上:

    WebSocket 不是建立在 HTTP 之上的,它是一个独立的协议。但是 WebSocket 握手使用的是 HTTP 协议,这是为了兼容现有的 HTTP 基础设施。

websocket和发布订阅机制的关系

  1. WebSocket 和发布订阅模式的关系:

    WebSocket 是一种全双工的通信协议,它允许服务器主动向客户端推送信息,客户端也可以主动向服务器发送信息,这样就使得它成为实现发布-订阅模式的一个很好的选择。在使用 WebSocket 进行实时通信时,常常会结合发布-订阅模式来设计。

websocket的建立流程

  1. WebSocket 的建立流程:

    • 客户端通过 HTTP 请求与 WebSocket 服务端协商建立连接。这个过程通常被称为“握手”(handshake)。如果服务器接受了连接请求,就会发回一个成功的 HTTP 响应,这个 HTTP 连接就升级成了 WebSocket 连接。
    • 握手过程中,客户端会发送一个 HTTP 请求到服务器,该请求包含一个 Upgrade: websocket 的头信息,表示尝试升级连接到 WebSocket。
    • 服务器在接收到这个请求并同意连接后,会返回一个包含 Upgrade: websocket 头的 HTTP 响应,这样,握手过程就完成了,客户端和服务器之间的通信就切换到了 WebSocket 协议。

以上这些都是 WebSocket 协议的基本内容。在实际应用中,你可能还需要根据需求和环境进行更深入的了解和研究。

TCP连接和释放

关于tcp的连接和释放,推荐看这篇文章理论经典:TCP协议的3次握手与4次挥手过程详解,有详细的流程

为什么需要三次握手,两次不行吗?

试想如果是用两次握手,则会出现下面这种情况:

如客户端发出连接请求,但因连接请求报文丢失而未收到确认,于是客户端再重传一次连接请求。后来收到了确认,建立了连接。数据传输完毕后,就释放了连接,客户端共发出了两个连接请求报文段,其中第一个丢失,第二个到达了服务端,但是第一个丢失的报文段只是在某些网络结点长时间滞留了,延误到连接释放以后的某个时间才到达服务端,此时服务端误认为客户端又发出一次新的连接请求,于是就向客户端发出确认报文段,同意建立连接,不采用三次握手,只要服务端发出确认,就建立新的连接了,此时客户端忽略服务端发来的确认,也不发送数据,则服务端一致等待客户端发送数据,浪费资源。

为什么第四次挥手后,客户端要等待2MSL时间才能释放客户端的资源?

1. TCP断开连接为什么要有四次挥手?

TCP是一种可靠的双向通信协议,所以每个方向都必须单独进行关闭。这个过程需要四步来确保双方都可以关闭他们的连接。前两次挥手是用来关闭初始的发送方的连接,后两次挥手是用来关闭另一方的连接。也就是说,发送“FIN”只是表示发送方不再发送数据,但是仍然可以接收数据;收到对方的“FIN”标志后才表示对方也不再发送数据,连接可以完全关闭。

2. TCP断开连接的最后一次挥手时,客户端和服务器为什么都要等待2MSL的时间?(可能面试官会问为什么客户端发完最后一个ACK给服务器后进入time_wait状态)

客户端在发送完最后一个ACK包后需要等待2MSL(Maximum Segment Lifetime,最大报文段生存时间)的时间,这主要有两个原因:

  • 确保最后一个ACK能够到达服务端。如果ACK丢失,服务端会重发FIN包,客户端再次发送ACK。

  • 避免“老的重复分组”在网络中滞留太久。在TCP连接关闭后的2MSL时间内,不允许同一源地址、目的地址、源端口、目的端口的连接建立,**这主要是为了防止老的连接的延迟数据包在新连接中被误认为是有效数据。**如果让客户端等待2MSL时间,则

举一个例子:

假设你有一个客户端和服务器之间的TCP连接,其源地址和端口为C1:1234,目的地址和端口为S1:80。在这个连接中,你发送了一个数据包P,但是由于网络延迟,P在网络中滞留了很久,没有立即到达服务器。然后你关闭了这个连接。

现在,你想要在同一个客户端和服务器之间开启一个新的连接,仍然使用C1:1234和S1:80。如果你在关闭旧连接后立即开启新连接,那么滞留在网络中的数据包P可能会到达服务器,被服务器误认为是新连接中的有效数据,这会导致数据混淆和错误。

为了防止这种情况,TCP规定在关闭连接后的2MSL时间内,不允许同一源地址、目的地址、源端口、目的端口的连接建立。这样,滞留在网络中的数据包P就有足够的时间在网络中消失,不会影响到新的连接。

所以2MSL是服务器和客户端都需要等待的吗?

是的,2MSL(Maximum Segment
Lifetime,最大报文段生存时间)是TCP连接在完全关闭前需要经过的时间,这段时间既适用于客户端,也适用于服务器。这是因为TCP连接是全双工的,也就是说,客户端和服务器两端都可以发送和接收数据。因此,无论是客户端还是服务器,都需要确保其发送的最后一个数据包(或者确认包)能够到达对端,并且需要等待足够的时间以便所有滞留在网络中的数据包都有机会到达对端或者被丢弃。这样,当新的连接在相同的端口和地址上建立时,就不会被这些“老的”数据包所影响。

3. MSL是多少

MSL的具体数值因系统和网络环境的不同而不同,但常见的数值为2分钟。这个值足够长,可以确保TCP的报文段在网络中的所有数据包都不再存在。然而,这个值在实际的网络环境中并不是固定的,可以根据实际的网络环境和需求进行设置。

4. 如果客户端的ACK丢失,那么服务端有超时机制,一定是小于MSL时间,所以会在这个时间内重传FIN,如果重传的FIN又丢失了呢?

如果服务端重发的FIN一直丢失,根据TCP的设计,服务器会尝试重发一定次数或者等待一段时间,如果仍然没有收到客户端的ACK,服务器会假设客户端已经接收到了FIN,并将连接视为关闭。虽然这可能会有一些资源没有被立即回收,但这个过程通常是自动的,不需要额外的干预。实际上,因为网络的可靠性,FIN包一直丢失的情况在现实中很少发生。

5. 服务端的第二次挥手到第三次挥手之间,服务端是不是还可以传输其他的数据给客户端?

是的,在服务器收到客户端的FIN报文并且回复ACK报文后,到发送自己的FIN报文这段时间,服务器是可以继续发送数据给客户端的。这是因为TCP是全双工的,一端发送FIN报文意味着“我已经没有数据要发送给你了”,并不影响另一端发送数据。

DDOS/DOS/SYN洪范攻击

三者之间的一些区别

1 DDOS为什么这么叫,它不是客户端拒绝做出第三次响应吗
2 和DOS有什么区别
3 和SYN攻击有什么区别

  1. DDoS(Distributed Denial of Service,分布式拒绝服务)攻击被这样称呼是因为这种攻击方式通常涉及到利用许多分散的系统(例如被感染的计算机或其他网络设备)发起大规模的攻击,以使目标系统无法提供正常的服务。DDoS攻击并不仅仅指拒绝做出第三次响应,它是一类攻击方式的总称,包括SYN洪水攻击、UDP洪水攻击、ICMP洪水攻击等。

  2. DOS(Denial of Service,拒绝服务)攻击和DDoS攻击的主要区别在于攻击的发起者。DOS攻击通常由单个源发起,而DDoS攻击则由多个源(分布在不同的网络位置)发起。由于DDoS攻击的分散性和规模,它比DOS攻击更难防御。

  3. SYN洪水攻击是一种具体的DoS/DDoS攻击方式,它利用TCP的三次握手机制。在SYN洪水攻击中,攻击者会发送大量的SYN请求到服务器,但不会对服务器的SYN+ACK响应进行确认(即不发出第三次握手),从而导致大量半开连接占用服务器资源,使正常用户无法连接服务器。因此,SYN洪水攻击可以看作是一种特殊的DoS/DDoS攻击。

常见的防御 SYN 攻击的方法有如下几种:

缩短超时(SYN Timeout)时间
增加最大半连接数
过滤网关防护
SYN cookies技术

解释一下上面几种预防方法

  1. 缩短超时(SYN Timeout)时间:在这种方法中,服务器会缩短等待客户端完成TCP三次握手的超时时间。如果在这个缩短的时间内,客户端没有发出第三次握手(即ACK),服务器将关闭半开放的连接,释放资源。这样,服务器就可以更快地处理掉那些不完全的连接,从而有更多的资源处理新的连接请求。

  2. 增加最大半连接数:服务器可以通过提高其允许的最大半开连接数来防御SYN洪水攻击。这可以增加服务器处理大量半开连接的能力。但是,这个方法并不能完全解决问题,因为攻击者可能会通过不断增加SYN请求的数量来超过服务器的最大半开连接数。

  3. 过滤网关防护:在网络的边界处(例如防火墙或路由器)部署过滤网关可以帮助防御SYN洪水攻击。这种设备可以分析进入网络的流量,识别出可能的SYN洪水攻击,并阻止这些攻击流量进入内部网络。

  4. SYN cookies技术:SYN cookies是一种非常有效的防御SYN洪水攻击的技术。在使用SYN cookies技术的服务器中,当收到SYN请求时,服务器并不立即分配资源创建半开连接,而是计算一个cookie(一个加密的哈希值),并将这个cookie作为初始序列号(ISN)在SYN+ACK响应中发送回客户端。如果客户端是合法的,并且真的想要建立连接,那么在第三次握手时,它将会发送一个ACK,其确认号是之前的ISN加一。这时,服务器收到ACK后,可以通过cookie验证这个ACK是否合法,如果合法就创建连接,否则忽略。这样,对于合法的连接请求,资源只在真正建立连接时才分配,而对于攻击造成的SYN请求,服务器并不分配资源,从而有效地防御了SYN洪水攻击。

猜你喜欢

转载自blog.csdn.net/yxg520s/article/details/131769665