Linux网络基础
OSI七层模型
OSI七层模型
- 物理层, 数据链路层, 网络层, 会话层 , 表示层, 应用层
五层协议
- 物理层, 数据链路层, 网络层, 传输层, 应用层

物理层: 定义物理设备的标准, 如网卡网线, 传输速率; 最终实现数据转换成电信号的传输
数据链路层: 定义了电信号的分组标准方式, 一组数据称之为一个数据帧, 这个标准遵循Ethernet以太网协议, 以太网规定了以下几件事:
- 数据帧分为
head和data两部分组成; 其中head长度为18字节- head: 发送者/源地址、接受者/目的地址(源地址6字节、目的地址6字节、数据类型6字节)
- 源地址:
MAC地址 - 目的地址:
MACA地址
- 源地址:
- data: 主要存放的是网络层整体的数据, 最长1500字节, 超过最大限制就分片发送;
- head: 发送者/源地址、接受者/目的地址(源地址6字节、目的地址6字节、数据类型6字节)
- 但凡接入互联网的主机必须有一块网卡, 网卡烧制了全世界唯一的mac地址;
- 有了以太网协议规定以后, 它能对数据分组, 也可以区分数据的意义, 还能找到目标主机地址, 就可以实现计算机通信; 但计算机是瞎的, 所以以太网通信采用的是”广播”方式;
网络层: 用来划分广播域, 如果广播域内主机要往广播域外的主机发送数据, 一定要有一个”网关/路由”帮其将数据转发到外部计算机; 网关和外界通信走的是路由协议. 其次网络层协议规定了以下几件事:
- 数据包分成:
head和data两部分组成:- head: 发送者/源地址、接受者/目的地址, 该地址为IP地址;
- data: 主要存放的是传输层整体的数据;
- 源地址:
IP地址 - 目的地址:
IP地址
- 源地址:
IP地址来划分广播域, 主要用来判断两台主机是否在同一广播域中;
- 一个合法IPV4地址组成部分: ip地址/子网掩码子网掩码计算器
- 如果计算出两台地址的广播域一样, 说明两台计算机处于同一个区域中;
传输层: 提供进程之间的逻辑通信
- 网络层帮我们划分子网, 数据链路层帮我们找到主机, 但一个主机有多个进程, 进程之间进行不同的网络通信, 那么当收到数据时, 如何区分数据是哪个进程的呢; 其实是通过端口来区分, 端口即应用程序与网卡关联的编号.
- 传输层分为
head和data两部分- head:
源端口、目标端口、协议(TCP/UDP) - data: 主要存放的是应用层整体的数据;
- head:
应用层: 为终端应用提供的服务, 如我们的浏览器交互时候需要用到的HTTP协议, 邮件发送的SMTP, 文件传输的FTP等.
TCP三次握手
TCP可靠数据传输协议: 为了实现可靠传输, 在通信之前需要先建立连接, 也叫”双向通路”, 就是说客户端与服务器要建立连接, 服务端与客户端也需要建立连接, 当然建立的这个双向通路她只是一个虚拟的链路, 不是用网线将两个设备真实的捆绑在一起;
虚拟链路的作用: 由于每次通信都需要拿到IP和Port, 那就意味着每次都需要查找, 建立好的虚拟通路, 下次两台主机之间就可以直接传输数据;
三次握手:

第一次: 客户端要与服务端建立连接, 需要发送请求消息;
第二次: 服务端接收到数据后, 返回一个确认操作(至此客户端到服务端链路建立成功);
第三次: 服务端还需要发送要与客户端建立连接的请求;
第四次: 客户端接收到数据后, 返回一个确认请求(至此服务端到客户端链路建立成功);
由于建立连接时没有数据传输, 所以第二次确认和第三次请求可以合并为一次发送;
TCP协议为了实现可靠传输, 通信双方要判断自己已经发送的数据包是否都被接收方收到, 如果没收到, 就需要重发. 为了实现这个需求, 就引出序号(seq)和确认号(ack)的使用
举例:
发送方在发送数据包时, 序列号(假设为123), 那么接收方收到这个数据包以后, 就可以回复一个确认号(124=123+1)告诉发送方”我已经收到了你的数据包, 你可以发送下一个数据包, 序号从124开始”, 这样发送方就可以知道哪些数据被接收, 哪些数据没被接收, 需要重发.

四次挥手
第一次挥手: 客户端(服务器也可以主动断开)向服务器说明想要关闭连接;
第二次挥手: 服务器会回复确认. 但不是立刻关闭, 因为此时服务器可能还有数据在传输中;
第三次挥手: 待服务器数据传输结束后, 服务端向客户端发出消息, 我要断开连接了;
第四次挥手: 客户端收到服务器断开信息后, 给予确认. 服务端收到确认后正式关闭.
网络状态转换
三次握手
- 客户端发送SYN包向服务端请求建立TCP连接, 客户端进入
SYN_SEND状态; - 服务端收到请求之后, 向客户端发送SYN+ACK的合成包, 同时自身进去
SYN_RECV状态; - 客户端收到回复后, 发送ACK信息, 自身进入
ESTABLISHED状态; - 服务端收到ACK数据之后, 进入
ESTABLISHED状态
四次挥手
- 客户端发送完整数据之后, 向服务器请求断开连接, 自身进入
FIN_WAIT_1状态; - 服务端收到FIN包之后, 回复ACK包表示已经收到, 但此时服务器可能还有数据没发送完成, 自身进入
CLOSE_WAIT状态, 表示对方已发送完成且请求关闭连接, 自身发送完成之后可以关闭连接; - 服务端数据发送完成后, 发送FIN包给客户端, 自身进入
LAST_ACK状态, 等待客户端ACK确认; - 客户端收到FIN包之后, 回复一个ACK包, 并进入
TIME_WAIT状态;
注意:
TIME_WAIT状态比较特殊, 当客户端收到服务端的FIN包时, 理想状态下, 是可以直接关闭连接了, 但有几个问题:
- 问题1: 如果网络不稳定, 可能服务端发送的一些数据包, 比服务端发送的FIN包还要晚;
- 问题2: 如果客户端回复的ACK包丢失了, 服务端就会一直处于
LAST_ACK状态, 如果客户端没有关闭, 那么服务端还会重传FIN包, 然后客户端继续确认;所以客户端如果ACK建立后立即关闭连接, 会导致数据不完整, 也肯呢个造成服务端无法释放连接, 所以此时客户端要等待
两个报文生成最大时长, 确保网络中没有任何遗留报文了, 再关闭连接如果机器TIME_WAIT过多, 会造成端口耗尽, 可以修改内核参数
tcp_tw_recycle = 1 # 端口重用

网关/路由
添加默认路由
1 | route add -net 0.0.0.0 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 | cat /etc/sysconfig/network-scripts/route-ens33 |
via为网关