计算机网络

157 阅读11分钟

计算机网络

  1. 请详细介绍一下 TCP 的三次握手和四次挥手机制?

    客户端和服务端都处于 CLOSE 状态。先是服务端主动监听某个端口,处于 LISTEN 状态 第一次握手 客户端会随机初始化序号(client_isn),将此序号置于 TCP 首部的「序号」字段中,同时把 SYN 标志位置为 1,表示 SYN 报文。接着把第一个 SYN 报文发送给服务端,表示向服务端发起连接,该报文不包含应用层数据,之后客户端处于 SYN-SENT 状态。 第二次握手 服务端收到客户端的 SYN 报文后,首先服务端也随机初始化自己的序号(server_isn),将此序号填入 TCP 首部的「序号」字段中,其次把 TCP 首部的「确认应答号」字段填入 client_isn + 1, 接着把 SYN 和 ACK 标志位置为 1。最后把该报文发给客户端,该报文也不包含应用层数据,之后服务端处于 SYN-RCVD 状态。 第三次握手 客户端收到服务端报文后,还要向服务端回应最后一个应答报文,首先该应答报文 TCP 首部 ACK 标志位置为 1 ,其次「确认应答号」字段填入 server_isn + 1 ,最后把报文发送给服务端,这次报文可以携带客户到服务端的数据,之后客户端处于 established 状态。服务端收到客户端的应答报文后,也进入 established 状态。

    第一次挥手 打算关闭连接,此时会发送一个 TCP 首部 FIN 标志位被置为 1 的报文,也即 FIN 报文,之后客户端进入 FIN_WAIT_1 状态。 第二次挥手 服务端收到该报文后,就向客户端发送 ACK 应答报文,接着服务端进入 CLOSE_WAIT 状态。 客户端收到服务端的 ACK 应答报文后,之后进入 FIN_WAIT_2 状态。 第三次挥手 等待服务端处理完数据后,也向客户端发送 FIN 报文,之后服务端进入 LAST_ACK 状态。 第四次挥手 客户端收到服务端的 FIN 报文后,回一个 ACK 应答报文,之后进入 TIME_WAIT 状态 服务端收到了 ACK 应答报文后,就进入了 CLOSE 状态,至此服务端已经完成连接的关闭。 客户端在经过 2MSL 一段时间后,自动进入 CLOSE 状态,至此客户端也完成连接的关闭。

  2. 为什么建立连接需要三次握手。第三次握手时,发送方可以携带其他数据吗?

    三次握手的原因: 三次握手才可以阻止重复历史连接的初始化(主要原因),在两次握手的情况下,服务端没有中间状态给客户端来阻止历史连接,导致服务端可能建立一个历史连接,造成资源浪费。 三次握手才可以同步双方的初始序列号 三次握手才可以避免资源浪费 第三次握手是可以携带数据的,前两次握手是不可以携带数据的

  3. 为什么需要四次挥手。详细讲讲time_wait和close_wait。

    关闭连接时,客户端向服务端发送 FIN 时,仅仅表示客户端不再发送数据了但是还能接收数据。 服务端收到客户端的 FIN 报文时,先回一个 ACK 应答报文,而服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送 FIN 报文给客户端来表示同意现在关闭连接。

    主动发起关闭连接的一方,才会有 TIME-WAIT 状态: 需要 TIME-WAIT 状态,主要是两个原因: 防止历史连接中的数据,被后面相同四元组的连接错误的接收; 保证「被动关闭连接」的一方,能被正确的关闭;等待足够的时间以确保最后的 ACK 能让被动关闭方接收,从而帮助其正常关闭。 过多的 TIME-WAIT 状态主要的危害有两种: 第一是占用系统资源,比如文件描述符、内存资源、CPU 资源、线程资源等; 第二是占用端口资源,端口资源也是有限的,一般可以开启的端口为 32768~61000,也可以通过 net.ipv4.ip_local_port_range参数指定范围。 优化过多的 TIME-WAIT: 打开 net.ipv4.tcp_tw_reuse 和 net.ipv4.tcp_timestamps 选项:在调用 connect() 函数时,内核会随机找一个 time_wait 状态超过 1 秒的连接给新的连接复用 net.ipv4.tcp_max_tw_buckets:当系统中处于 TIME_WAIT 的连接一旦超过这个值时,系统就会将后面的 TIME_WAIT 连接状态重置 程序中使用 SO_LINGER ,应用强制使用 RST 关闭:调用close后,会立该发送一个RST标志给对端,该 TCP 连接将跳过四次挥手,也就跳过了TIME_WAIT状态,直接关闭 如果服务端要避免过多的 TIME_WAIT 状态的连接,就永远不要主动断开连接,让客户端去断开,由分布在各处的客户端去承受 TIME_WAIT

    CLOSE_WAIT 状态是「被动关闭方」才会有的状态,而且如果「被动关闭方」没有调用 close 函数关闭连接,那么就无法发出 FIN 报文,从而无法使得 CLOSE_WAIT 状态的连接转变为 LAST_ACK 状态。

3.5 为什么 TIME_WAIT 等待的时间是 2MSL?

MSL 与 TTL 的区别: MSL 的单位是时间,而 TTL 是经过路由跳数。所以 MSL 应该要大于等于 TTL 消耗为 0 的时间,以确保报文已被自然消亡。
TTL 的值一般是 64,Linux 将 MSL 设置为 30 秒,意味着 Linux 认为数据报文经过 64 个路由器的时间不会超过 30 秒,如果超过了,就认为报文已经消失在网络中了。
TIME_WAIT 等待 2 倍的 MSL,比较合理的解释是: 网络中可能存在来自发送方的数据包,当这些发送方的数据包被接收方处理后又会向对方发送响应,所以一来一回需要等待 2 倍的时间。
  1. SYN超时和洪泛攻击是什么?解决策略有哪些?

    在 TCP 三次握手的时候,Linux 内核会维护两个队列,分别是: 半连接队列,也称 SYN 队列; 全连接队列,也称 accept 队列; SYN 攻击方式最直接的表现就会把 TCP 半连接队列打满,这样当 TCP 半连接队列满了,后续再在收到 SYN 报文就会丢弃,导致客户端无法和服务端建立连接。

    避免 SYN 攻击方式,可以有以下四种方法: 调大 netdev_max_backlog;当网卡接收数据包的速度大于内核处理的速度时,会有一个队列保存这些数据包。控制该队列的最大值 增大 TCP 半连接队列; 开启 tcp_syncookies;可以在不使用 SYN 半连接队列的情况下成功建立连接,相当于绕过了 SYN 半连接来建立连接。 减少 SYN+ACK 重传次数

  2. TCP和UDP有什么特点,有什么区别?

    1. TCP面向连接,UDP无连接;
    2. TCP可靠传输,使用流量控制和拥塞控制,UDP不可靠传输;
    3. TCP只能一对一通信,UDP支持一对一,一对多,多对多
    4. TCP面向字节流,UDP面向报文
    5. TCP首部最小20字节最大60字节,UDP首部仅8字节
    6. TCP可靠传输的应用,如:文件传输,UDP适用于实时应用,如:IP电话、视频会议、直播
  3. 在浏览器的地址栏中输入URL,后续的网络都发生了什么,尽可能讲一讲。

    1. 浏览器对 URL 进行解析之后,确定了 Web 服务器和文件名,接下来就是根据这些信息来生成 HTTP 请求消息了。
    2. 浏览器会先看自身有没有对这个域名的缓存,如果有,就直接返回,如果没有,就去问操作系统,操作系统也会去看自己的缓存,如果有,就直接返回,如果没有,再去 hosts 文件看,也没有,才会去问「本地 DNS 服务器」, 还没有会通过DNS查询服务器域名对应的 IP 地址。
    3. 应用程序(浏览器)通过调用 Socket 库,来委托协议栈工作。协议栈的上半部分有两块,分别是负责收发数据的 TCP 和 UDP 协议,协议栈的下面一半是用 IP 协议控制网络包收发操作。
    4. 先查询 ARP 缓存,如果其中已经保存了对方的 MAC 地址,就不需要发送 ARP 查询,直接使用 ARP 缓存中的地址。而当 ARP 缓存中不存在对方 MAC 地址时,则发送 ARP 广播查询, 网卡驱动程序控制网卡发送数据。
    5. 数据包抵达服务器后,服务器会先扒开数据包的 MAC 头部,查看是否和服务器自己的 MAC 地址符合,符合就将包收起来。接着继续扒开数据包的 IP 头,发现 IP 地址符合,根据 IP 头中协议项,知道自己上层是 TCP 协议。扒开 TCP 的头,里面有序列号,需要看一看这个序列包是不是我想要的,如果是就放入缓存中然后返回一个 ACK,如果不是就丢弃。TCP头部里面还有端口号, HTTP 的服务器正在监听这个端口号。服务器自然就知道是 HTTP 进程想要这个包,于是就将包发给 HTTP 进程。
    6. 服务器的 HTTP 进程看到,封装响应数据,于是就把这个网页封装在 HTTP 响应报文里。然后数据包也要加上 TCP、IP、MAC 头部,从网卡出去,交由交换机转发到出城的路由器,直到发送给客户端。
  4. HTTP和HTTPS有哪些区别?

    HTTP 是超文本传输协议,信息是明文传输,存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷,在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议,使得报文能够加密传输。 HTTP 连接建立相对简单, TCP 三次握手之后便可进行 HTTP 的报文传输。而 HTTPS 在 TCP 三次握手之后,还需进行 SSL/TLS 的握手过程,才可进入加密报文传输。 两者的默认端口不一样,HTTP 默认端口号是 80,HTTPS 默认端口号是 443。 HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的。

  5. GET和POST有哪些区别?

    1. get传参方式是通过地址栏URL传递,post传参方式参数URL不可见;
    2. get传递数据是通过URL进行传递,对传递的数据长度是受到URL大小的限制,URL最大长度是2048个字符。
    3. get方法是安全、幂等、可被缓存的。 post没有长度限制
    4. get后退不会有影响,post后退会重新进行提交
    5. get请求可以被缓存,post不可以被缓存
    6. get只支持ASCII字符,post没有字符类型限制 优点: 1.安全性比get传参方式好 2.post没有字符和编码的限制,能发送的数据类型更多· 3.post传送数据没有大小限制,比get可以发送的更多的数据
  6. COOKIE和SESSION有什么区别?又有哪些联系?

    token:
    令牌,是用户身份的验证方式。
    最简单的token组成:uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名)
    session:
    会话,代表服务器与浏览器的一次会话过程,这个过程是连续的,也可以时断时续。
    cookie中存放着一个sessionID,请求时会发送这个ID;
    session因为请求(request对象)而产生;
    session是一个容器,可以存放会话过程中的任何对象;
    session的创建与使用总是在服务端,浏览器从来都没有得到过session对象;
    session是一种http存储机制,目的是为武装的http提供持久机制。
    cookie:
    储存在用户本地终端上的数据,服务器生成,发送给浏览器,下次请求统一网站给服务器。Cookie的大小只有4kb,它是一种纯文本文件,每次发起HTTP请求都会携带Cookie。
    SessionStorage:
    由于SessionStorage具有时效性,所以可以用来存储一些网站的游客登录的信息,还有临时的浏览记录的信息。当关闭网站之后,这些信息也就随之消除了。
    LocalStorage:
    存储的信息较大(大小一般为5MB),LocalStorage是持久储存,并不会随着页面的关闭而消失,除非主动清理,不然会永久存在,仅储存在本地,不像Cookie那样每次HTTP请求都会被携,LocalStorage受到同源策略的限制,即端口、协议、主机地址有任何一个不相同,都不会访问。
    sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。