其他分享
首页 > 其他分享> > 43.第十章 网络协议和管理配置(四)

43.第十章 网络协议和管理配置(四)

作者:互联网

3.2 transport 层

在这里插入图片描述
TCP和UDP
在这里插入图片描述
在这里插入图片描述

3.2.1 TCP Transmission Control Protocol

3.2.1.1 TCP特性

工作在传输层

面向连接协议

全双工协议

半关闭

将数据打包成段,排序

确认机制

数据恢复,重传

错误检查

流量控制,滑动窗口

拥塞控制,慢启动和拥塞避免算法

更多关于tcp的内核参数,可参看man 7 tcp

3.2.1.2 TCP包头结构

TCP包头

在这里插入图片描述

TCP包头常见选项:

范例:

五要素
协议
IP 源 目的
端口 源 目的

TCP 10.0.0.100:12345--->1.1.1.1:80

[root@rocky8 ~]# cat /etc/services

3.2.1.3 TCP协议PORT

在这里插入图片描述
传输层通过port号,确定应用层协议,范围0-65535

维基百科:https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers

IANA互联网数字分配机构负责域名,数字资源,协议分配

范例:调整客户端的动态端口范围

[root@rocky8 ~]# cat /proc/sys/net/ipv4/ip_local_port_range
32768	60999
[root@rocky8 ~]# echo 20000 62000 > /proc/sys/net/ipv4/ip_local_port_range
[root@rocky8 ~]# cat /proc/sys/net/ipv4/ip_local_port_range
20000	62000

范例:

[root@rocky8 ~]# dnf -y install man-pages

[root@rocky8 ~]# man 2 socket
[root@rocky8 ~]# dnf -y install nc

[root@rocky8 ~]# nc -l 9527

[root@centos7 ~]# nc 172.31.1.8 9527
-bash: nc: command not found
[root@centos7 ~]# yum -y install nc
[root@centos7 ~]# nc 172.31.1.8 9527
[root@rocky8 ~]# ss -nt
State          Recv-Q           Send-Q                     Local Address:Port                     Peer Address:Port           Process          
ESTAB          0                52                            172.31.1.8:22                         172.31.0.1:63293                           
ESTAB          0                0                             172.31.1.8:22                         172.31.0.1:63772                           
ESTAB          0                0                             172.31.1.8:9527                       172.31.0.7:47226 

[root@rocky8 ~]# nc -l 9527

[root@centos7 ~]# nc 172.31.1.8 9527

[root@centos7 ~]# nc 172.31.1.8 9527
i am centos8

[root@centos7 ~]# nc 172.31.1.8 9527
i am centos8

[root@centos7 ~]# nc 172.31.1.8 9527
i am centos8
i am centos7

[root@rocky8 ~]# nc -l 9527
i am centos8
i am centos7

[root@rocky8 ~]# lsof -i :9527
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nc      1833 root    3u  IPv4  31658      0t0  TCP *:9527 (LISTEN)
nc      1833 root    4u  IPv4  31659      0t0  TCP rocky8:9527->172.31.0.7:47230 (ESTABLISHED)
#9527 端口使用

#一旦建立连接,就释放了端口,不在占用端口,别人就可以继续访问

范例:找到端口冲突的应用程序

[root@rocky8 ~]# nc -l 22
nc: Address already in use #提示22端口被占用

[root@rocky8 ~]# nc -l 2222
[root@rocky8 ~]# ss -ntl
State           Recv-Q           Send-Q                     Local Address:Port                     Peer Address:Port          Process          
LISTEN          0                1                                0.0.0.0:2222                          0.0.0.0:*                              
LISTEN          0                128                              0.0.0.0:22                            0.0.0.0:*                              
LISTEN          0                128                                 [::]:22                               [::]:*               
[root@rocky8 ~]# lsof -i :22
-bash: lsof: command not found
[root@rocky8 ~]# dnf -y install lsof
[root@rocky8 ~]# lsof -i :22 #查看端口被谁占用
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd     774 root    4u  IPv4  26024      0t0  TCP *:ssh (LISTEN)
sshd     774 root    6u  IPv6  26035      0t0  TCP *:ssh (LISTEN)
sshd    1266 root    5u  IPv4  27742      0t0  TCP rocky8:ssh->172.31.0.1:63293 (ESTABLISHED)
sshd    1278 root    5u  IPv4  27742      0t0  TCP rocky8:ssh->172.31.0.1:63293 (ESTABLISHED)
sshd    1505 root    5u  IPv4  29340      0t0  TCP rocky8:ssh->172.31.0.1:63772 (ESTABLISHED)
sshd    1507 root    5u  IPv4  29340      0t0  TCP rocky8:ssh->172.31.0.1:63772 (ESTABLISHED)

[root@rocky8 ~]# ss -ntlp #-p  选项可以查看每个端口被哪个应用程序使用
State         Recv-Q        Send-Q               Local Address:Port               Peer Address:Port       Process                              
LISTEN        0             1                          0.0.0.0:2222                    0.0.0.0:*           users:(("nc",pid=1504,fd=3))        
LISTEN        0             128                        0.0.0.0:22                      0.0.0.0:*           users:(("sshd",pid=774,fd=4))       
LISTEN        0             128                           [::]:22                         [::]:*           users:(("sshd",pid=774,fd=6))  
[root@rocky8 ~]# ss -ntlp |grep 22
LISTEN 0      1            0.0.0.0:2222      0.0.0.0:*    users:(("nc",pid=1504,fd=3)) 
LISTEN 0      128          0.0.0.0:22        0.0.0.0:*    users:(("sshd",pid=774,fd=4))
LISTEN 0      128             [::]:22           [::]:*    users:(("sshd",pid=774,fd=6))

范例:判断端口是否正在打开

[root@rocky8 ~]# < /dev/tcp/127.0.0.1/22
[root@rocky8 ~]# echo $?
0

[root@rocky8 ~]# < /dev/tcp/127.0.0.1/80
-bash: connect: Connection refused
-bash: /dev/tcp/127.0.0.1/80: Connection refused
[root@rocky8 ~]# echo $?
1

TCP端口号通信过程

在这里插入图片描述
TCP序列和确认号
在这里插入图片描述
TCP确认和固定窗口
在这里插入图片描述
在这里插入图片描述
TCP滑动窗口
在这里插入图片描述
#ACK 3 表示期望你下次发3,变相告诉你3没收到,让你重发

TCP 滑动窗⼝是什么?
在这里插入图片描述
TCP 是每发送⼀个数据,都要进⾏⼀次确认应答。只有上一个收到了回应才发送下一个,这样效率会非常低,因此引进了滑动窗口的概念.

其实就是在发送方设立一个缓存区间,将已发送但未收到确认的消息缓存起来,假如一个窗口可以发送 5 个 TCP 段,那么发送方就可以连续发送 5 个 TCP 段,然后就会将这 5 个 TCP 段的数据缓存起来,这 5 个 TCP 段是有序的,只要后面的消息收到了 ACK ,那么不管前面的是否有收到 ACK,都代表成功,窗⼝⼤⼩是由接收方决定的

窗⼝⼤⼩就是指不需要等待应答,还可以发送数据的大小

3.2.1.4 三次握手和四次挥手

建立连接

在这里插入图片描述
TCP三次握手
在这里插入图片描述
TCP 建立连接的过程是怎样的?

为什么是三次握手???

在这里插入图片描述

范例: 三次握手

#wireshark抓包分析
(ip.src == 10.0.0.101 and ip.dst == 10.0.0.102) || (ip.dst == 10.0.0.101 and ip.src == 10.0.0.102)

在这里插入图片描述

TCP四次挥手

MSL :Maximum Segment Lifetime
在这里插入图片描述
TCP 断开连接的过程是怎样的?

第四次挥手为什么要等待2MSL(60s)

在这里插入图片描述
首先 2MSL 的时间是从客户端(A)接收到 FIN 后发送 ACK 开始计时的。如果在 TIME-WAIT 时间内,因为客户端(A)的 ACK 没有传输到服务端(B),客户端(A)又接收到了服务端(B)重发的 FIN 报文,那么 2MSL 时间会被重置。等待 2MSL 原因如下

包括 ACK 是以上哪两种情况,A 都需要等待,要取这两种情况等待时间的最大值,以应对最坏的情况发生,这个最坏情况是:去向ACK消息最大存活时间(MSL) + 来向FIN消息的最大存活时间(MSL)。这刚好是2MSL,这个时间,足以使得原来连接的数据包在网络中消失

为什么是四次挥手?

在这里插入图片描述
因为 tcp 可以在发送数据的同时也能接受数据,要实现可靠的连接关闭,A 发出结束报文 FIN,收到 B 确认后 A 知道自己没有数据需要发送了,B 知道 A 不再发送数据了,自己也不会接收数据了,但是此时 A 还是可以接收数据,B 也可以发送数据;当 B 发出 FIN 报文的时候此时两边才会真正的断开连接,读写分开。

在这里插入图片描述
范例: wireshark 查看四次挥手
在这里插入图片描述
范例:

[root@rocky8 ~]# 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:*                               
LISTEN          0               1                                0.0.0.0:9527                          0.0.0.0:*                               
ESTAB           0               0                             172.31.1.8:22                         172.31.0.1:63293                           
ESTAB           0               0                             172.31.1.8:9527                       172.31.0.7:47230                           
ESTAB           0               52                            172.31.1.8:22                         172.31.0.1:63772                           
LISTEN          0               128                                 [::]:22                               [::]:*                               
[root@centos7 ~]# ss -nat
State       Recv-Q Send-Q                          Local Address:Port                                         Peer Address:Port              
LISTEN      0      128                                         *:22                                                      *:*                  
LISTEN      0      100                                 127.0.0.1:25                                                      *:*                  
FIN-WAIT-1  0      1                                  172.31.0.7:47230                                          172.31.1.8:9527               
ESTAB       0      0                                  172.31.0.7:22                                             172.31.0.1:63812              
ESTAB       0      0                                  172.31.0.7:22                                             172.31.0.1:63813              
LISTEN      0      128                                      [::]:22                                                   [::]:*                  
LISTEN      0      100                                     [::1]:25                                                   [::]:*

[root@rocky8 ~]# iptables -A INPUT -s 172.31.0.7 -j DROP
[root@rocky8 ~]# iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  *      *       172.31.0.7           0.0.0.0/0           

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination  
 
 [root@centos7 ~]# ssh 172.31.1.8
 
 [root@centos7 ~]# ss -nta
State       Recv-Q Send-Q                          Local Address:Port                                         Peer Address:Port              
LISTEN      0      128                                         *:22                                                      *:*                  
LISTEN      0      100                                 127.0.0.1:25                                                      *:*                  
SYN-SENT    0      1                                  172.31.0.7:56896                                          172.31.1.8:22  #这里有 SYN-SENT 状态                
ESTAB       0      0                                  172.31.0.7:22                                             172.31.0.1:50521              
FIN-WAIT-1  0      1                                  172.31.0.7:47230                                          172.31.1.8:9527               
ESTAB       0      52                                 172.31.0.7:22                                             172.31.0.1:50520              
ESTAB       0      0                                  172.31.0.7:22                                             172.31.0.1:63812              
ESTAB       0      0                                  172.31.0.7:22                                             172.31.0.1:63813              
LISTEN      0      128                                      [::]:22                                                   [::]:*                  
LISTEN      0      100                                     [::1]:25  

[root@rocky8 ~]# iptables -F

[root@centos7 ~]# ssh 172.31.1.8
root@172.31.1.8's password: 

[root@centos7 ~]# ss -nta
State       Recv-Q Send-Q                          Local Address:Port                                         Peer Address:Port              
LISTEN      0      128                                         *:22                                                      *:*                  
LISTEN      0      100                                 127.0.0.1:25                                                      *:*                  
ESTAB       0      0                                  172.31.0.7:22                                             172.31.0.1:50521              
ESTAB       0      0                                  172.31.0.7:56900                                          172.31.1.8:22  #7和8已经  ESTAB 状态               
ESTAB       0      52                                 172.31.0.7:22                                             172.31.0.1:50520              
ESTAB       0      0                                  172.31.0.7:22                                             172.31.0.1:63812              
ESTAB       0      0                                  172.31.0.7:22                                             172.31.0.1:63813              
TIME-WAIT   0      0                                  172.31.0.7:56898                                          172.31.1.8:22                 
LISTEN      0      128                                      [::]:22                                                   [::]:*                  
LISTEN      0      100                                     [::1]:25                                                   [::]:* 

[root@rocky8 ~]# 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:*                               
LISTEN          0               1                                0.0.0.0:9527                          0.0.0.0:*                               
ESTAB           0               0                             172.31.1.8:22                         172.31.0.7:56900                           
ESTAB           0               0                             172.31.1.8:22                         172.31.0.1:63293                           
ESTAB           0               0                             172.31.1.8:9527                       172.31.0.7:47230                           
ESTAB           0               52                            172.31.1.8:22                         172.31.0.1:63772                           
LISTEN          0               128                                 [::]:22                               [::]:* 

[root@centos7 ~]# iptables -A INPUT -s 172.31.1.8 -j DROP
[root@centos7 ~]# iptables -vnL
Chain INPUT (policy ACCEPT 65 packets, 4848 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  *      *       172.31.1.8           0.0.0.0/0           

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 43 packets, 4468 bytes)
 pkts bytes target     prot opt in     out     source               destination 
 
[root@centos7 ~]# ssh 172.31.1.8

[root@rocky8 ~]# 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:*                               
LISTEN            0               1                              0.0.0.0:9527                          0.0.0.0:*                               
SYN-RECV          0               0                           172.31.1.8:22                         172.31.0.7:56902  #现在就是SYN-RECV状态                          
ESTAB             0               0                           172.31.1.8:22                         172.31.0.1:63293                           
ESTAB             0               0                           172.31.1.8:9527                       172.31.0.7:47230                           
ESTAB             0               52                          172.31.1.8:22                         172.31.0.1:63772                           
LISTEN            0               128                               [::]:22                               [::]:* 

#两次握手只实现了单次确认,只有第三次才能双向确认

[root@centos7 ~]# iptables -F

范例: 查看 MSL

[root@rocky8 ~]# sysctl net.ipv4.tcp_fin_timeout
net.ipv4.tcp_fin_timeout = 60
[root@rocky8 ~]# cat /proc/sys/net/ipv4/tcp_fin_timeout
60

3.2.1.5 有限状态机 FSM:Finite State Machine

虚线:服务器 实线:客户端
在这里插入图片描述

客户端先发送一个FIN给服务端,自己进入FIN_WAIT_1状态,这时等待接收服务端报文,该报文会有三种可能:

1、只收到服务器的ACK,客户端会进入FIN_WAIT_2状态,后续当收到服务端的FIN时,回应发送一个ACK,会进入到TIME_WAIT状态,这个状态会持续2MSL(TCP报文段在网络中的最大生存时间, RFC1122标准的建议值是2min).客户端等待2MSL,是为了当最后一个ACK丢失时,可以再发送一次。因为服务端在等待超时后会再发送一个FIN给客户端,进而客户端知道ACK已丢失

2、只有服务端的FIN时,回应一个ACK给服务端,进入CLOSING状态,然后接收到服务端的ACK时,进入TIME_WAIT状态

3、同时收到服务端的ACK和FIN,直接进入TIME_WAIT状态

客户机端的三次握手和四次挥手状态转换
在这里插入图片描述
服务器端的三次握手和四次挥手状态转换
在这里插入图片描述

3.2.1.6 sync半连接和accept全连接队列

在这里插入图片描述
/proc/sys/net/ipv4/tcp_max_syn_backlog 未完成连接队列大小,默认值128,建议调整大小为1024以上

/proc/sys/net/core/somaxconn 完成连接队列大小,默认值128,建议调整大小为1024以上

范例:修改半连接队列

[root@rocky8 ~]# cat /proc/sys/net/ipv4/tcp_max_syn_backlog
128
[root@rocky8 ~]# echo 1024 > /proc/sys/net/ipv4/tcp_max_syn_backlog
[root@rocky8 ~]# cat /proc/sys/net/ipv4/tcp_max_syn_backlog
1024

范例:修改全连接队列

[root@rocky8 ~]# cat /proc/sys/net/core/somaxconn
128
[root@rocky8 ~]# echo 1024 > /proc/sys/net/core/somaxconn
[root@rocky8 ~]# cat /proc/sys/net/core/somaxconn
1024

TCP 半连接队列和全连接队列是什么?
在这里插入图片描述
服务端收到客户端发出的 SYN 请求后,会把这个连接信息存储到半链接队列(SYN 队列)

服务端收到第三次握⼿的 ACK 后,内核会把连接从半连接队列移除,然后创建新的完全的连接,并将其添加到全连接队列(accept 队列),等待进程调⽤ accept 函数时把连接取出来。

这两个队列都是有大小限制的,当超过容量后就会将链接丢弃,或者返回 RST 包。

3.2.1.7 TCP超时重传

异常网络状况下(开始出现超时或丢包),TCP控制数据传输以保证其承诺的可靠服务

TCP服务必须能够重传超时时间内未收到确认的TCP报文段。为此,TCP模块为每个TCP报文段都维护一个重传定时器,该定时器在TCP报文段第一次被发送时启动。如果超时时间内未收到接收方的应答,TCP模块将重传TCP报文段并重置定时器。至于下次重传的超时时间如何选择,以及最多执行多少次重传,就是TCP的重传策略

与TCP超时重传相关的两个内核参数:

范例:

#最小超时重传次数
[root@rocky8 ~]# cat /proc/sys/net/ipv4/tcp_retries1
3

#最大超时重传次数
[root@rocky8 ~]# cat /proc/sys/net/ipv4/tcp_retries2
15

粘包/拆包是怎么发生的?怎么解决这个问题?

TCP 发送数据时会根据 TCP 缓冲区的实际情况进行包的划分,一个完整的包可能会被 TCP 拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是 TCP 粘包和拆包问题。

在这里插入图片描述
发生 TCP 粘包原因:

发生 TCP 拆包原因:

解决方案:
在这里插入图片描述

3.2.1.8 拥塞控制

网络中的带宽、交换结点中的缓存和处理机等,都是网络的资源。在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可承受的能力,网络的性能就会变坏。此情况称为拥塞

TCP为提高网络利用率,降低丢包率,并保证网络资源对每条数据流的公平性。即所谓的拥塞控制

TCP拥塞控制的标准文档是RFC 5681,其中详细介绍了拥塞控制的四个部分:慢启动(slow start)、拥塞避免(congestion avoidance)、快速重传(fast retransmit)和快速恢复(fast recovery)。拥塞控制算法在Linux下有多种实现,比如reno算法、vegas算法和cubic算法等。它们或者部分或者全部实现了上述四个部分

当前所使用的拥塞控制算法

/proc/sys/net/ipv4/tcp_congestion_control

范例:

#拥塞控制算法
[root@rocky8 ~]# cat /proc/sys/net/ipv4/tcp_congestion_control
cubic

发送方一直发送数据,但是接收方处理不过来怎么办?(流量控制)

如果接收方处理不过来,发送方就会触发重试机制再次发送数据,然而这个是有性能损耗的,为了解决这个问题,TCP 就提出了流量控制,为的就是让发送方知道接受方的处理能力

也就是说,每次接收方接受到数据后会将剩余可处理数据的大小告诉发送方

比如接受方滑动窗口可用大小为400字节,发送方发送过来100字节的数据,那么接收方剩余可用滑动窗口大小就为300字节,这是发送方就知道下次返送数据的大小范围了。

但是这里有一个问题,数据会存放在缓冲区,但是这个缓冲区是操作系统控制的,当系统繁忙的时候,会缩减缓冲区减小,可能就会造成丢包的问题
在这里插入图片描述

如: 发送方接收方窗口大小各为200字节,发送方发送100字节的给接收方,此时双方各剩100字节,但是此时操作系统非常忙,将接收方的缓存区减少了50字节,这时接收方就会告诉发送方,我还有50字节可用,但是在接收方发送到达之前,发送方是不知道的,只会看到自己还有100字节可用,那么就继续发送数据,如果发送了80字节数据,那么接收方缓存区大小为50字节,就会丢失30字节的数据,也就是会发生丢包现象。

我们会发现,这个问题发生的原因就是减少了缓存,又收缩了窗口大小,所以 TCP 是不允许同时减少缓存⼜收缩窗⼝的。

3.2.1.9 内核TCP参数优化

参看帮助: man tcp

编辑文件/etc/sysctl.conf,加入以下内容:然后执行 sysctl -p 让参数生效。

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

作用说明:

标签:网络协议,报文,第十章,43,TCP,tcp,0.0,172.31,root
来源: https://blog.csdn.net/qq_25599925/article/details/120944140