OSI七层模型

  • OSI七层模型

    • 物理层, 数据链路层, 网络层, 会话层 , 表示层, 应用层
  • 五层协议

    • 物理层, 数据链路层, 网络层, 传输层, 应用层

image-20211019081109976

物理层: 定义物理设备的标准, 如网卡网线, 传输速率; 最终实现数据转换成电信号的传输

数据链路层: 定义了电信号的分组标准方式, 一组数据称之为一个数据帧, 这个标准遵循Ethernet以太网协议, 以太网规定了以下几件事:

  1. 数据帧分为headdata两部分组成; 其中head长度为18字节
    • head: 发送者/源地址、接受者/目的地址(源地址6字节、目的地址6字节、数据类型6字节)
      • 源地址: MAC地址
      • 目的地址: MACA地址
    • data: 主要存放的是网络层整体的数据, 最长1500字节, 超过最大限制就分片发送;
  2. 但凡接入互联网的主机必须有一块网卡, 网卡烧制了全世界唯一的mac地址;
  3. 有了以太网协议规定以后, 它能对数据分组, 也可以区分数据的意义, 还能找到目标主机地址, 就可以实现计算机通信; 但计算机是瞎的, 所以以太网通信采用的是”广播”方式;

网络层: 用来划分广播域, 如果广播域内主机要往广播域外的主机发送数据, 一定要有一个”网关/路由”帮其将数据转发到外部计算机; 网关和外界通信走的是路由协议. 其次网络层协议规定了以下几件事:

  1. 数据包分成: headdata两部分组成:
    • head: 发送者/源地址、接受者/目的地址, 该地址为IP地址;
    • data: 主要存放的是传输层整体的数据;
      • 源地址: IP地址
      • 目的地址: IP地址
  2. IP地址来划分广播域, 主要用来判断两台主机是否在同一广播域中;
    - 一个合法IPV4地址组成部分: ip地址/子网掩码子网掩码计算器
    - 如果计算出两台地址的广播域一样, 说明两台计算机处于同一个区域中;

传输层: 提供进程之间的逻辑通信

  • 网络层帮我们划分子网, 数据链路层帮我们找到主机, 但一个主机有多个进程, 进程之间进行不同的网络通信, 那么当收到数据时, 如何区分数据是哪个进程的呢; 其实是通过端口来区分, 端口即应用程序与网卡关联的编号.
  1. 传输层分为headdata两部分
    • head: 源端口目标端口协议(TCP/UDP)
    • data: 主要存放的是应用层整体的数据;

应用层: 为终端应用提供的服务, 如我们的浏览器交互时候需要用到的HTTP协议, 邮件发送的SMTP, 文件传输的FTP等.

TCP三次握手

TCP可靠数据传输协议: 为了实现可靠传输, 在通信之前需要先建立连接, 也叫”双向通路”, 就是说客户端与服务器要建立连接, 服务端与客户端也需要建立连接, 当然建立的这个双向通路她只是一个虚拟的链路, 不是用网线将两个设备真实的捆绑在一起;

虚拟链路的作用: 由于每次通信都需要拿到IP和Port, 那就意味着每次都需要查找, 建立好的虚拟通路, 下次两台主机之间就可以直接传输数据;

三次握手:

image-20211019090955422

  • 第一次: 客户端要与服务端建立连接, 需要发送请求消息;

  • 第二次: 服务端接收到数据后, 返回一个确认操作(至此客户端到服务端链路建立成功);

  • 第三次: 服务端还需要发送要与客户端建立连接的请求;

  • 第四次: 客户端接收到数据后, 返回一个确认请求(至此服务端到客户端链路建立成功);

  • 由于建立连接时没有数据传输, 所以第二次确认和第三次请求可以合并为一次发送;

  • TCP协议为了实现可靠传输, 通信双方要判断自己已经发送的数据包是否都被接收方收到, 如果没收到, 就需要重发. 为了实现这个需求, 就引出序号(seq)和确认号(ack)的使用

  • 举例:

    发送方在发送数据包时, 序列号(假设为123), 那么接收方收到这个数据包以后, 就可以回复一个确认号(124=123+1)告诉发送方”我已经收到了你的数据包, 你可以发送下一个数据包, 序号从124开始”, 这样发送方就可以知道哪些数据被接收, 哪些数据没被接收, 需要重发.

image-20211019091746360

四次挥手

第一次挥手: 客户端(服务器也可以主动断开)向服务器说明想要关闭连接;

第二次挥手: 服务器会回复确认. 但不是立刻关闭, 因为此时服务器可能还有数据在传输中;

第三次挥手: 待服务器数据传输结束后, 服务端向客户端发出消息, 我要断开连接了;

第四次挥手: 客户端收到服务器断开信息后, 给予确认. 服务端收到确认后正式关闭.

image-20211019092054666

网络状态转换

三次握手

  1. 客户端发送SYN包向服务端请求建立TCP连接, 客户端进入SYN_SEND状态;
  2. 服务端收到请求之后, 向客户端发送SYN+ACK的合成包, 同时自身进去SYN_RECV状态;
  3. 客户端收到回复后, 发送ACK信息, 自身进入ESTABLISHED状态;
  4. 服务端收到ACK数据之后, 进入ESTABLISHED状态
image-20211019093147121

四次挥手

  1. 客户端发送完整数据之后, 向服务器请求断开连接, 自身进入FIN_WAIT_1状态;
  2. 服务端收到FIN包之后, 回复ACK包表示已经收到, 但此时服务器可能还有数据没发送完成, 自身进入CLOSE_WAIT状态, 表示对方已发送完成且请求关闭连接, 自身发送完成之后可以关闭连接;
  3. 服务端数据发送完成后, 发送FIN包给客户端, 自身进入LAST_ACK状态, 等待客户端ACK确认;
  4. 客户端收到FIN包之后, 回复一个ACK包, 并进入TIME_WAIT状态;

注意:

TIME_WAIT状态比较特殊, 当客户端收到服务端的FIN包时, 理想状态下, 是可以直接关闭连接了, 但有几个问题:

  • 问题1: 如果网络不稳定, 可能服务端发送的一些数据包, 比服务端发送的FIN包还要晚;
  • 问题2: 如果客户端回复的ACK包丢失了, 服务端就会一直处于LAST_ACK状态, 如果客户端没有关闭, 那么服务端还会重传FIN包, 然后客户端继续确认;

所以客户端如果ACK建立后立即关闭连接, 会导致数据不完整, 也肯呢个造成服务端无法释放连接, 所以此时客户端要等待两个报文生成最大时长, 确保网络中没有任何遗留报文了, 再关闭连接

如果机器TIME_WAIT过多, 会造成端口耗尽, 可以修改内核参数

tcp_tw_recycle = 1 # 端口重用

image-20211019095132405

网关/路由

添加默认路由

1
2
3
route add -net 0.0.0.0 gw 10.0.0.2
或者
route add default gw 10.0.0.2

添加设备路由

去往1.1.1.0/24网段, 从ens33接口出

1
route add -net 1.1.1.0/24 dev ens33

去往1.1.1.1主机, 从ens33接口出

1
route add -host 1.1.1.0/24 dev ens33

添加网关路由

去往1.1.1.0/24网段, 交给10.0.0.2转发

1
route add -host 1.1.1.0/32 gw 10.0.0.2

去往1.1.1.1, 交给10.0.0.2转发

1
route add -host 1.1.1.1/32 gw 10.0.0.2

添加永久路由

1
2
3
cat /etc/sysconfig/network-scripts/route-ens33
1.1.1.0/24 dev ens33
1.1.1.0/24 via 1.1.1.2

via为网关