目录
3、TCP(Transmission Control Protocol)
1、回顾
1.1、各层的数据格式
物理层:比特流;数据链路层:帧;网络层:包;传输层:段
1.2、TCP/IP模型与OSI模型的比较
相同点:
- 两者都是以协议栈的概念为基础
- 协议栈中的协议彼此相互独立
- 下层对上层提供服务
不同点:
- OSI是先有模型;TCP/IP是先有协议,后有模型
- OSI适用于各种协议栈;TCP/IP只适用于TCP/IP网络
- 层数数量不同,OSI是7层,TCP/IP是5层
2、传输层的作用
- 网络层(IP层)提供点到点的连接。从一台电脑到另一台电脑
- 传输层提供端到端(端口,port)的连接。从一个端口到另一个端口。端口号方便区别各种应用。
网络通信最基本的四元组(源IP、目的IP、源端口、目的端口)
windows里的a程序访问kafka,Windows首先通过IP地址找到它,解封装之后,找到端口号,送给kafka。
linux内核是管网络的;网络的封装和解封装都是内核里完成的;
2.1、不同的进程会监听不同的端口(牢记⭐)
- mysql:3306
- ssh:22
- telnet:23
- dns:53
- nginx:80
- kafka:9092
- QQ:8000(要是不知道可以抓包看看,科来或者tcpdump)
- flask:5000
若是你真的不知道哪个服务对应着哪个端口,你可以查看"/etc/services"文件,这个文件会记录哪个协议默认使用哪个端口,支持tcp还是udp。
[root@fttsaxf ~]# cat /etc/services |awk '$1=="ssh"{print $1,$2}'
ssh 22/tcp
ssh 22/udp
ssh 22/sctp
[root@fttsaxf ~]# cat /etc/services |awk '$1=="ssh"{print $0}' # $0,表示打印出所有,且这里边要使用双引号
ssh 22/tcp # The Secure Shell (SSH) Protocol
ssh 22/udp # The Secure Shell (SSH) Protocol
ssh 22/sctp # SSH
2.1.1、lsof和netstat查看端口号的使用和区别
(1)netstat
[root@fttsaxf ~]# netstat -anplut
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1060/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1285/master
tcp 0 36 192.168.29.128:22 192.168.29.1:57405 ESTABLISHED 1579/sshd: root@pts
tcp6 0 0 :::22 :::* LISTEN 1060/sshd
tcp6 0 0 ::1:25 :::* LISTEN 1285/master
udp 0 0 127.0.0.1:323 0.0.0.0:* 692/chronyd
udp6 0 0 ::1:323 :::* 692/chronyd
# -a,显示所有的信息
# -n,以数字形式显示
# -p,显示程序的名字 program name
# -t,tcp;-u,udp
# -l,显示处于监听状态的
Proto,表示当前的协议;Recv—Q,就是接收队列;Send—Q,就是发送队列;Local Address,就是本地主机 ,":"后边的是端口;Foreign Address,表示外边的机器的地址,"0.0.0.0:*"表示任意的地址和任意的端口;State,是状态;PID/Program name,pid号和名字。
状态中,Listen,表示监听:打开了某个端口等着别人来访问;ESTABLISHED,建立连接:已经连接成功。
(2)lsof
[root@fttsaxf bin]# lsof -i:22 # 查看22号端口被什么进程占用了
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 1049 root 3u IPv4 19026 0t0 TCP *:ssh (LISTEN)
sshd 1049 root 4u IPv6 19035 0t0 TCP *:ssh (LISTEN)
sshd 1571 root 3u IPv4 20267 0t0 TCP fttsaxf:ssh->192.168.29.1:61366 (ESTABLISHED)
#查看某个进程打开了哪些文件、加载库、依赖关系
[root@fttsaxf bin]# lsof -p 1571
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 1571 root cwd DIR 253,0 282 64 /
sshd 1571 root rtd DIR 253,0 282 64 /
sshd 1571 root txt REG 253,0 852856 441276 /usr/sbin/sshd
sshd 1571 root mem REG 253,0 555888 1011 /usr/lib64/libfreeblpriv3.so
区别:
- netstat无权限控制,lsof有权限控制,只能看到本用户
- lsof能看到pid和用户,可以找到哪个进程占用了这个端口
2.1.2、看进程消耗量多少流量
nethogs,也可以知道哪些进程和外边进行通信了。输入nethogs之后,你会看到这样
NetHogs version 0.8.5
PID USER PROGRAM DEV SENT RECEIVED
1576 root sshd: root@pts/0 ens33 0.143 0.059 KB/sec
? root unknown TCP 0.000 0.000 KB/sec
TOTAL 0.143 0.059 KB/sec
然后你再进入自己的IP地址的网站,多刷新几次,就会出现下面图片中显示的样子,这就是显示了哪个进程消耗了流量
2.1.3、查看其他机器或者自己的端口是否打开⭐⭐⭐
method1:nc
# -w,限制扫描的时间
# -z,Only scan for listening daemons,without sending any data to them
[root@fttsaxf ~]# nc -w 1 -z 192.168.0.1 80
[root@fttsaxf ~]# echo $?
1
# 0,表示端口打开了;1,表示端口没有打开
method2:nmap
探测一个机器或者整个局域网里机器开放了哪些端口
[root@fttsaxf menu]# nmap 192.168.29.2 # 这个IP地址是别人的,这个命令只是扫描了一些知名的端口,不可能是扫描所有的端口
Starting Nmap 6.40 ( http://nmap.org ) at 2022-04-07 08:59 CST
Nmap scan report for 192.168.29.2
Host is up (0.00015s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
53/tcp open domain
MAC Address: 00:50:56:EE:E5:6D (VMware)
Nmap done: 1 IP address (1 host up) scanned in 1.91 seconds
这个命令要基于防火墙的允许,才能够查找防火墙允许外部能访问的端口
2.2、查看网络流量
method1:dstat
# -m,启用内存统计信息(已使用、缓冲区、缓存、空闲)
# 这个命令中,-a就是相当于默认的参数,和直接输入"dstat"的结果是一样的
# -N,查看网卡使用的流量
[root@fttsaxf ~]# dstat -am -N ens33
----total-cpu-usage---- -dsk/total- -net/ens33- ---paging-- ---system-- ------memory-usage-----
usr sys idl wai hiq siq| read writ| recv send| in out | int csw | used buff cach free
0 0 99 0 0 0| 135k 9396B| 0 0 | 0 0 | 87 156 | 248M 2108k 260M 1310M
0 0 100 0 0 0| 0 0 | 60B 1042B| 0 0 | 50 85 | 248M 2108k 260M 1310M
0 0 100 0 0 0| 0 0 | 60B 426B| 0 0 | 51 79 | 248M 2108k 260M 1310M
0 0 100 0 0 0| 0 0 | 60B 426B| 0 0 | 53 88 | 248M 2108k 260M 1310M
method2:glances⭐⭐⭐
[root@fttsaxf ~]# glances # 这个命令显示出来的内容很详细
fttsaxf (CentOS Linux 7.9.2009 64bit / Linux 3.10.0-1160.el7.x86_64) Uptime: 0:44:02
CPU [ 1.9%] CPU 1.9% nice: 0.0% MEM 20.8% SWAP 0.0% LOAD 2-core
MEM [ 20.8%] user: 1.0% irq: 0.0% total: 1.78G total: 2.00G 1 min: 0.07
SWAP [ 0.0%] system: 0.6% iowait: 0.0% used: 379M used: 0 5 min: 0.05
idle: 98.4% steal: 0.0% free: 1.41G free: 2.00G 15 min: 0.05
NETWORK Rx/s Tx/s TASKS 109 (125 thr), 1 run, 108 slp, 0 oth sorted automatically
ens33 448b 2Kb
lo 0b 0b CPU% MEM% VIRT RES PID USER NI S TIME+ IOR/s IOW/s Command
3.8 0.8 225M 15.3M 2018 root 0 R 0:02.49 0 0 /usr/bin/py
DISK I/O R/s W/s 0.3 0.0 0 0 50 root 0 S 0:03.60 0 0 kworker/0:1
dm-0 0 0 0.3 0.9 561M 17.0M 1056 root 0 S 0:01.52 0 0 /usr/bin/py
dm-1 0 0 0.3 0.3 218M 5.54M 1060 root 0 S 0:00.35 0 0 /usr/sbin/r
sda 0 0 0.0 0.1 25.9M 1.74M 678 root 0 S 0:00.20 0 0 /usr/lib/sy
sda1 0 0 0.0 0.0 0 0 23 root -20 S 0:00.00 0 0 bioset
sda2 0 0
sr0 0 0
2022-04-07 08:42:25 No warning or critical alert detected
2.3、传输层的协议(TCP和UDP)
(1)TCP(Transmission Control Protocol)
- 传输控制协议
- 可靠的(体现在有计时器、有校验和、有确认包)、面向连接(体现在三次握手和四次断开)的协议
- 传输效率低
- 是一种面向连接的、可靠的、基于字节流的传输层通信协议。
可以用打电话来理解,要两个人都接,确定双方都存在,所以可靠性高一些
业务场景:MySQL、http、ssh
(2)UDP(User Datagram Protocol)
- 用户数据报协议
- 不可靠的、无连接的服务
- 传输效率高
可以用发短信来理解,发过去,并不需要对面确定并且回复
业务场景:QQ、dns、dhcp
数据到了传输层可以选择这两种协议中的一种
3、TCP(Transmission Control Protocol)
工作原理:
3.1、TCP的封装格式
所以tcp 头部长度为20~60
🍓[端口号]🍓
端口号的范围:2^16=65536,即0~65535
有些端口号已经分配给了一些经典的服务或者系统预留了,即0~1023。注册端口号为1024-49151。剩下的端口号叫动态端口号或私有端口号,为49152-65535。
封装:源IP1.1,目的IP1.2;http产生的端口是80;https产生的端口是443;56341是随机产生的端口,80的目的端口号。这些都可以用抓包看到的。
若是我们使用flask(默认情况下监听5000端口)非要用80端口(nginx的端口)可以吗?可以的,只要你的机器里没有启用nginx,就不会发生冲突们就可以使用。
🍓[32位序列号]🍓
0~2^32-1范围内,数据段标记,用于到目的端对到达包的重组,因为MTU最大只是为1500,所以个大的文件不能一次性就传输过去,所以在传输层的时候,每个数据都要打个包并且进行编号。
一次TCP通信(从TCP连接建立到断开)过程中某一个传输方向上的字节流的每个字节的编号。假设主机A和主机B进行TCP通信,A发送给B的第一个TCP报文段中,序号值被系统初始化为某个随机值ISN(Initial Sequence Number,初始序号值)。那么在该传输方向上(从A到B),后续的TCP报文段中序号值将被系统设置成ISN加上该报文段所携带数据的第一个字节在整个字节流中的偏移。例如,某个TCP报文段传送的数据是字节流中的第1025~2048字节,那么该报文段的序号值就是ISN+1025.另外一个传输方向(从B到A)的TCP报文段的序号值也具有相同的含义。
🍓[32位确认号]🍓
是可靠性的表现。0~2^32-1范围内,对发送端的确认信息,告诉发送端这个序号之前的数据段都受到了。
🍓[六个标志位或者控制位]🍓一定要记下⭐⭐⭐
这六个标志位只能是0或者1
- URG,紧急指针有效位,与16位紧急指针配合使用
- ACK,确认序列号有效位,表明该数据包包含确认信息。只要回复了对方的发送过来的包,这个ACK就是1
- PSH,通知接收端立即将数据提交给用户进程,不在缓存中停留,等待更多的数据。提醒内核的
- RST,reset重置位。为1时,请求重新建立TCP连接
- SYN,sync同步:为1的时候,表示第一次请求建立连接
- FIN,finish。为1时数据发送完毕,请求断开连接
🍓[16位窗口大小]🍓
滑动窗口的大小(0~65535),指明本地可接受数据的字节数。
若是为0的话,表示不能够接收数据了;若是为1000的话,表示只能够接受1000字节的数据。TCP就是靠这个来进行流量控制。
3.1.1、MSS和MTU
MSS(TCP最大报文长度)位于应用层,MTU(最大传输单元)位于网络层。
MSS最大为1460=1500-20(ip头部)-20(tcp头部范围为20~60)
3.2、tcp的序列号为什么要随机生成
在TCP的三次握手中,采用随机产生的初始化序列号进行请求,这样做主要是出于网络安全的因素着想。如果不是随机产生初始序列号,黑客将会以很容易的方式获取到你与其他主机之间通信的初始化序列号,并且伪造序列号进行攻击,这已经成为一种很常见的网络攻击手段。
- 从安全性考虑,黑客不会那么容易猜到序列号,不会伪造一些确认序列包,从而对服务器发起攻击。ISN由M(随着时间的推移单调递增)和和MD5(由四元组确定的MD5值)。若是当ISN到达32位保存的最大值,序列号到达尽头的时候,序列号又会从0开始(这种现象叫做序列号回绕),那么这种情况下就无法判断出哪个是以前的包,哪个是之后的包。那么怎么解决呢?
- 在选项中加上时间戳(timestamp),比如里面有发送方的时间戳,和接收方的时间戳。那么时间戳就可以用来计算往返时间、确认数据包的先后顺序。