「网络协议」网络协议基础

1. 分层网络协议

  1. OSI七层网络协议:物理层,数据链路层,网络层,传输层(TCP/UDP),会话层,表示层,应用层
  2. TCP/IP协议分层(可以理解为OSI的一种实现):网络接口层,网络层,传输层(TCP/UDP),应用层

2. TCP通信协议简介:

  • 面向连接的、可靠的、基于字节流的 传输层通信协议
  • 将应用层的数据流分割成报文段并发送给目标节点的TCP层
  • 数据包都有序号,对方收到则发送ACK确认,未收到则重传
  • 使用校验和来校验数据在传输过程中是否有误
  • 报文头中的ACK(确认序号标志),SYN(同步序号,用于建立连接过程)

3. TCP建立连接的三次握手

  1. 第一次:建立连接时,客户端发送SYN包(syn=j)到服务器,并进入SYS_SEND状态,等待服务器确认;
  2. 第二次:服务器收到SYN包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即 SYN+ACK包,此时服务器进入SYN_RECV状态;
  3. 第三次:客户端收到SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务端进入ESTABLISHED状态,完成三次握手。

4. 为什么需要三次握手

  • 为了初始化Sequence Number的初始值(通信双方要互相通知对方自己的Sequence Number,要作为以后数据通信的序号,以保证接收到的数据不会因为网络传输问题而乱序,TCP会用这个序号拼接数据)

5. 首次握手的隐患—SYN超时

  • 服务端收到客户端的SYN,回复SYN-ACK的时候未收到ACK确认
  • 服务端不断尝试(重发SYN-ACK)直至超时,Linux默认等待63秒才断开连接(默认重试5次,重试间隔1s开始,每次翻倍,即1+2+4+8+16+32=63)
  • 可能遭受SYN Flood的风险(syn攻击,又称为ddos攻击)

6. 什么是SYN Flood攻击

  • 客户端恶意的向某个服务器端口发送大量的SYN包,则可以使服务器打开大量的半开连接,分配TCB,从而消耗大量的服务器资源,同时也使得正常的连接请求无法被相应。而攻击发起方的资源消耗相比较可忽略不计。
  • SYN Flood是当前最流行的DoS(拒绝服务攻击)与DDoS(分布式拒绝服务攻击)的方式之一。

7. Linux针对SYN Flood的防护措施

  • SYN队列满后,通过tcp_syncookies参数回发SYN Cookies
  • 若为正常连接则客户端会回发SYN Cookies,直接建立连接

8. 建立连接后,客户端出现故障怎么办(保活机制)

  • 向对方发送保活探测报文,如果未收到响应则继续发送
  • 尝试次数达到保活探测树仍未收到响应则中断连接

9. TCP终止连接的四次挥手(以客户端主动为例)

  1. 第一次:客户端发送一个FIN(seq=u),用来关闭客户端到服务器的数据传送,客户端进入FIN_WAIT_1状态;
  2. 第二次:服务器收到FIN,发回一个ACK(ack=u+1),确认序号为收到的序号+1(和SYN一样,一个FIN将占用一个序号),服务端进入CLOSE_WAIT状态;
  3. 第三次:服务端发送一个FIN(seq=w),用来关闭服务端到客户端的数据传送,服务端进入LAST_ACK状态;
  4. 第四次:客户端收到FIN,发回一个ACK(ack=w+1),将确认序号设置为收到序号+1,客户端进入TIME_WAIT状态,服务端进入CLOSED状态,完成四次挥手。

10. 存在TIME_WAIT状态的原因

  • 保证TCP全双工连接的可靠释放,确保有足够时间让对方收到ACK包
  • 避免新旧来凝结混淆,使旧数据包在网络中因过期而失效

11. 为什么需要四次挥手

  • 因为全双工,发送方和接收方都需要FIN报文和ACK报文

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

  • 对方关闭socket连接,我方忙于读或写,没有及时关闭连接
    • 检查代码,特别是释放资源的代码
    • 检查配置,特别是处理请求的线程配置

13. UDP简介

  • 面向非连接
  • 不维护连接状态,支持同时向多个客户端传输相同消息
  • 数据包报头只有8个字节,额外开销小
  • 吞吐量只受限于数据生成速率、传输速率以及机器性能
  • 尽最大努力交付,不保证可靠性,不需要维持复杂的链接状态表
  • 面向报文,不对应用程序提交的报文信息进行拆分或者合并

14. TCP和UDP的区别

  • 面向连接 vs 无连接
  • 可靠性和有序性 vs 不保证
  • 全双工的字节流 vs 全双工的数据报
  • 效率低 vs 速度快
  • 重量级 vs 轻量级

15. Http协议简介

  • 基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等),Hyper Text Transfer Protocol(超文本传输协议)的缩写。
  • 简单快速:客户向服务器请求服务时,只需传送请求方法(GET、HEAD、POST等)和路径。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
  • 灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
  • 无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
  • 无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快
  • 支持B/S及C/S模式

16. HTTP 请求/响应的步骤

  1. 客户端连接到Web服务器
    • 一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接。例如,https://chaooo.github.io
  2. 发送HTTP请求
    • 通过TCP套接字,客户端向Web服务器发送一个文本的请求报文,一个请求报文由请求行、请求头部、空行和请求数据4部分组成。
  3. 服务器接受请求并返回HTTP响应
    • Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据4部分组成。
  4. 释放连接TCP连接
    • 若connection 模式为close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若connection 模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求;
  5. 客户端浏览器解析HTML内容
    • 客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。然后解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示。

17. 在浏览器地址栏键入URL,按下回车之后会经历以下流程:

  1. 浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址;
  2. 解析出 IP 地址后,根据该 IP 地址和默认端口 80,和服务器建立TCP连接;
  3. 浏览器发出读取文件(URL 中域名后面部分对应的文件)的HTTP 请求,该请求报文作为 TCP 三次握手的第三个报文的数据发送给服务器;
  4. 服务器对浏览器请求作出响应,并把对应的 html 文本发送给浏览器;
  5. 释放 TCP连接;
  6. 浏览器将该 html 文本并显示内容;

 

18. HTTP之状态码

  1. 状态代码有三位数字组成,第一个数字定义了响应的类别,共分五种类别:
    • 1xx:指示信息–表示请求已接收,继续处理
    • 2xx:成功–表示请求已被成功接收、理解、接受
    • 3xx:重定向–要完成请求必须进行更进一步的操作
    • 4xx:客户端错误–请求有语法错误或请求无法实现
    • 5xx:服务器端错误–服务器未能实现合法的请求
  2. 常见状态码:
    • 200 OK //客户端请求成功
    • 400 Bad Request //客户端请求有语法错误,不能被服务器所理解
    • 401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
    • 403 Forbidden //服务器收到请求,但是拒绝提供服务
    • 404 Not Found //请求资源不存在,eg:输入了错误的URL
    • 500 Internal Server Error //服务器发生不可预期的错误
    • 503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常

19. HTTPS和HTTP的区别:

  1. https协议需要到CA申请证书(收费),http不需要。
  2. https密文传输,http明文传输。
  3. http使用80端口,https默认使用443端口。
  4. https = http + 加密 + 认证 + 完整性保护

20. Socket简介

  • Socket是对TCP/IP协议的抽象,是操作系统对外开发的接口

  • 基于tcp协议的编程模型

    • 服务器:
      1. 创建ServerSocket类型的对象并提供端口号;
      2. 等待客户端的连接请求,调用accept方法;
      3. 使用输入输出流进行通信;
      4. 关闭Socket;
    • 客户端:
      1. 创建Socket类型的对象并提供服务器的通信地址和端口号;
      2. 使用输入输出流进行通信;
      3. 关闭Socket;
  • 基于udp协议的编程模型

    • 主机A(接收方):
      1. 创建DatagramSocket类型的对象,并提供端口号;
      2. 创建DatagramPacket类型的对象,用于接收发来的数据;
      3. 从Socket中接收数据,调用**receive()**方法;
      4. 关闭Socket并释放有关的资源;
    • 主机B(发送方)
      1. 创建DatagramSocket类型的对象;
      2. 创建DatagramPacket类型的对象,并提供接收方的IP地址和端口号;
      3. 通过Socket发送数据,调用**send()**方法;
      4. 关闭Socket并释放有关的资源;