循环冗余检验CRC是一种检验方法,而FCS是添加在数据后面的帧检验序列。CRC 检验只能保证接收端接收到的帧没有差错,至于有没有出现帧丢失,帧重复,帧失序,是无法判断的。

CRC

循环冗余校验(Cyclic Redundancy Check, CRC)是一种根据网络数据包或计算机文件等数据产生简短固定位数校验码的一种信道编码技术(算法),主要用来检测或校验数据传输或者保存后可能出现的错误。它是利用除法及余数的原理来作错误侦测的。

FCS

帧校验序列码 FCS ( Frame Check Sequences) 是为提高通信的可靠性设置的。将每一帧中的第一个字符@到该帧中正文的最后一个ASCII 字符作“异或”运算, 并将异或的结果转换为两个ASCII码, 便得到了FCS , 它作为帧的一部分发送到接收端。接收端计算出收到的帧的FCS , 如果与发送端传送过来的FCS 不同, 可以判定通信有误。

帧校验序列(FCS)是指特别的检测码字符被添加到在一个通信协议中的帧中进行检错和纠错。发送主机在整个帧中有一个检测码随着发送。接收主机在整个帧中的检测码使用相同的运算法则,并将它与接收到的 FCS 相比较。这样,它能够探测是否任何数据在运输中丢失或被改变。它可能当时丢失这个数据,和请求错误帧的重传。一个循环冗余码校验常被用来估算 FCS。

FCS 字段:包含帧的 32 位循环冗余校验 (CRC), 数据链路层帧方式接入协议(LAPF)中的字段,是一个16比特的序列。它具有很强的检错能力,它能检测出在任何位置上的 3 个以内的错误、所有的奇数个错误、16个比特之内的连续错误以及大部分的大量突发错误。

ethernet-frame.gif

octets:(Bytes)字节
Frame:帧

参考:

循环冗余检验算法(CRC)与帧检验序列(FCS)

帧检验序列(FCS)

最大传输单元(Maximum Transmission Unit,MTU)用来通知对方所能接受数据服务单元的最大尺寸,说明发送方能够接受的有效载荷大小。
是包或帧的最大长度,一般以字节记。如果MTU过大,在碰到路由器时会被拒绝转发,因为它不能处理过大的包。如果太小,因为协议一定要在包(或帧)上加上包头,那实际传送的数据量就会过小,这样也划不来。大部分操作系统会提供给用户一个默认值,该值一般对用户是比较合适的。

简介

以太网和802.3对数据帧的长度都有一个限制,其最大值分别是1500字节和1492字节。链路层的这个特性称为MTU,即最大传输单元。不同类型网络的数帧长度大多数都有一个上限。如果IP层有一个数据报要传,而且数据帧的长度比链路层的MTU还大,那么IP层就需要进行分片( fragmentation),即把数据报分成干片,这样每一片就都小于MTU。

当同一个网络上的两台主机互相进行通信时,该网络的MTU是非常重要。但是如果两台主机之间的通信要通过多个网络,每个网络的链路层可能有不同的MTU,那么这时重要的不是两台主机所在网络的MTU的值,而是两台主机通信路径中的最小MTU,称为 路径 MTU( Path mtu,PMTU)。

两台主机之间的PMTU不一定是个常数,它取决于当时所选择的路径,而且路由选择也不一定是对称的(从A到B的路由可能与从B到A的路由不同),因此,PMTU在两个方向上不一定是一致的。
RFC1191描述了PMTU的发现机制,即确定路径MTU的方法。ICMP的不可到达错误采用的就是这种方法, traceroute程序也是用这种方法来确定到达目的节点的PMT的。

MTU字节

在远端节点的配置响应中将包含在该信道使用的实际的MTU大小,信道的方向是流向本地节点,MTU值取在configReq中的MTU和远端节点的输出MTU能力中最小值。该MTU只能用于这个信道,不能用于相反方向的信道。
MTU字段:2个字节。

MTU字段表示发起请求方可以接受的最大的L2CAP分组净荷(按字节计)。MTU是非对称的,请求的发送方指定在该信道上它可以接收的MTU值。L2CAP的实现必须支持最小的48字节的MTU值。缺省值是672字节。

用途

MTU是网络调节的重要因素,因为包中的额外开销量相当高。高的MTU减少了头信息浪费的字节数。对大量数据传输尤其重要,而对小于MTU的传输没有影响。因此,注意配置传输大量数据流的服务器(如文件服务器和FTPH&.务器)上的MTU。

选择MTU时,规则是选择传输中不需分段的最大MTU。如果网络使用一种媒体类型,缺省的设置就可以。选择比媒体最大值更小的MTU并没有好处,整个数据报会因为每个包的错误而重发。换言之,不能重发单个段。

IP分片与重组

数据链路不同,最大传输单元( Maximum transmission Unit,MTU)也不同,由于IP协议是数据链路的上一层,所以它必须不受数据链路的MTU大小的影响能够加以利用。当IP数据报太大时,就要采用分片技术,以保证数据帧不大于要过的网络的MTU。

IP协议除了具有路由寻址功能外,另一个重要的功能就是IP数据报的分片处理。每个数据链路层能够确定发送的一个帧的最大长度称为最大传输单元。在Ethernet中,MTU为1500字节;在FDDI中,MTU为4352字节;在 IP over ATM中,MTU为9180字节。

如果要发送的IP数据报比数据链路层的MTU大,则无法发送该数据报。对于来自于上一层的IP协议,当要求发送的IP数据报比数据链路层的MTU大时,必把该数据报分割成多个IP数据报才能发送。另外,在进行通信的各台主机之间,存在着MTU不同的数据链路;在发送的过程中,也有MTU缩小的情况发生。当出现上述情况时,在发送过程中必须有一台能够进行分片处理的路由器。

接收端主机必须对经过分片处理后的IP数据报进行还原处理。在中继路由器中,虽然路由器进行了分片处理,但并不进行还原处理。另外,经分片处理的IP数据报只有经过还原处理后才能还原成原来的IP数据报,才可以向上一层的模块传递数据。

d009b3de9c82d158ccbfd28051420ed8bc3eb135e4e3.png

参考:

最大传输单元

查看Linux内核版本

1
2
cat /proc/version
uname -a

查看Linux系统版本

1
2
3
4
5
6
7
8
9
10
# 这个命令适用于所有的Linux发行版,包括RedHat、SUSE、Debian…等发行版。
# 如果未安装,需要命令:yum install redhat-lsb -y
lsb_release -a

# 只适合Redhat系的Linux
cat /etc/redhat-release
file /bin/bash

# 适用于所有的Linux发行版
cat /etc/issue

1
2
3
4
git rm -r --cached .  # 不删除本地文件
git rm -r --f .    # 删除本地文件
git rm --cached 1.txt # 删除readme1.txt的跟踪,并保留在本地。
git rm --f 1.txt # 删除readme1.txt的跟踪,并且删除本地文件。

已经被纳入了版本管理中,则修改 .gitignore 是无效的。

解决方法就是先把本地缓存删除(改变成未track状态),然后再提交:

1
2
3
4
5
git rm -r --cached .
git add .

# 提交暂存区到本地仓库中
git commit -m 'update .gitignore'

自定义函数

自定义函数规则:

  • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。
  • 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
  • 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
  • 函数内容以冒号 : 起始,并且缩进。
  • return [表达式] 结束函数,选择性地返回一个值给调用方,不带表达式的 return 相当于返回 None。
    阅读全文 »

条件语句

if、elif、else 来进行逻辑判断

格式:

1
2
3
4
5
6
7
8
if 判断条件1:
执行语句1...
elif 判断条件2:
执行语句2...
elif 判断条件3:
执行语句3...
else:
执行语句4...
阅读全文 »

GRANT语法

在 MySQL 中,拥有 GRANT 权限的用户才可以执行 GRANT 语句,其语法格式如下:

1
2
3
4
GRANT priv_type [(column_list)] ON database.table
TO user [IDENTIFIED BY [PASSWORD] 'password']
[, user[IDENTIFIED BY [PASSWORD] 'password']] ...
[WITH with_option [with_option]...]

实例:

1
2
3
4
GRANT SELECT,INSERT,DELETE,UPDATE ON *.* TO 'root'@'192.125.30.123' IDENTIFIED BY '123456' WITH GRANT OPTION;

# 刷新
FLUSH PRIVILEGES;

取消权限:

revoke all on *.* from root@localhost;

  • priv_type 参数表示权限类型;
  • columns_list 参数表示权限作用于哪些列上,省略该参数时,表示作用于整个表;
  • database.table 用于指定权限的级别;
  • user 参数表示用户账户,由用户名和主机名构成,格式是“‘username‘@’hostname’”;
  • IDENTIFIED BY 参数用来为用户设置密码;
  • password 参数是用户的新密码。

WITH 关键字后面带有一个或多个 with_option 参数。这个参数有 5 个选项,详细介绍如下:

  • GRANT OPTION:被授权的用户可以将这些权限赋予给别的用户;
  • MAX_QUERIES_PER_HOUR count:设置每个小时可以允许执行 count 次查询;
  • MAX_UPDATES_PER_HOUR count:设置每个小时可以允许执行 count 次更新;
  • MAX_CONNECTIONS_PER_HOUR count:设置每小时可以建立 count 个连接;
  • MAX_USER_CONNECTIONS count:设置单个用户可以同时具有的 count 个连接。

GRANT 语句中可用于指定权限级别的值有以下几类格式:

  • *:表示当前数据库中的所有表。
  • *.*:表示所有数据库中的所有表。
  • db_name.*:表示某个数据库中的所有表,db_name 指定数据库名。
  • db_name.tbl_name:表示某个数据库中的某个表或视图,db_name 指定数据库名,tbl_name 指定表名或视图名。
  • db_name.routine_name:表示某个数据库中的某个存储过程或函数,routine_name 指定存储过程名或函数名。
  • TO 子句:如果权限被授予给一个不存在的用户,MySQL 会自动执行一条 CREATE USER 语句来创建这个用户,但同时必须为该用户设置密码。

数据库权限的权限类型

权限名称 对应user表中的字段 说明
SELECT Select_priv 表示授予用户可以使用 SELECT 语句访问特定数据库中所有表和视图的权限。
INSERT Insert_priv 表示授予用户可以使用 INSERT 语句向特定数据库中所有表添加数据行的权限。
DELETE Delete_priv 表示授予用户可以使用 DELETE 语句删除特定数据库中所有表的数据行的权限。
UPDATE Update_priv 表示授予用户可以使用 UPDATE 语句更新特定数据库中所有数据表的值的权限。
REFERENCES References_priv 表示授予用户可以创建指向特定的数据库中的表外键的权限。
CREATE Create_priv 表示授权用户可以使用 CREATE TABLE 语句在特定数据库中创建新表的权限。
ALTER Alter_priv 表示授予用户可以使用 ALTER TABLE 语句修改特定数据库中所有数据表的权限。
SHOW VIEW Show_view_priv 表示授予用户可以查看特定数据库中已有视图的视图定义的权限。
CREATE ROUTINE Create_routine_priv 表示授予用户可以为特定的数据库创建存储过程和存储函数的权限。
ALTER ROUTINE Alter_routine_priv 表示授予用户可以更新和删除数据库中已有的存储过程和存储函数的权限。
INDEX Index_priv 表示授予用户可以在特定数据库中的所有数据表上定义和删除索引的权限。
DROP Drop_priv 表示授予用户可以删除特定数据库中所有表和视图的权限。
CREATE TEMPORARY TABLES Create_tmp_table_priv 表示授予用户可以在特定数据库中创建临时表的权限。
CREATE VIEW Create_view_priv 表示授予用户可以在特定数据库中创建新的视图的权限。
EXECUTE ROUTINE Execute_priv 表示授予用户可以调用特定数据库的存储过程和存储函数的权限。
LOCK TABLES Lock_tables_priv 表示授予用户可以锁定特定数据库的已有数据表的权限。
ALL 或 ALL PRIVILEGES 或 SUPER Super_priv 表示以上所有权限/超级权限

表权限的权限类型

权限名称 对应user表中的字段 说明
SELECT Select_priv 授予用户可以使用 SELECT 语句进行访问特定表的权限
INSERT Insert_priv 授予用户可以使用 INSERT 语句向一个特定表中添加数据行的权限
DELETE Delete_priv 授予用户可以使用 DELETE 语句从一个特定表中删除数据行的权限
DROP Drop_priv 授予用户可以删除数据表的权限
UPDATE Update_priv 授予用户可以使用 UPDATE 语句更新特定数据表的权限
ALTER Alter_priv 授予用户可以使用 ALTER TABLE 语句修改数据表的权限
REFERENCES References_priv 授予用户可以创建一个外键来参照特定数据表的权限
CREATE Create_priv 授予用户可以使用特定的名字创建一个数据表的权限
INDEX Index_priv 授予用户可以在表上定义索引的权限
ALL 或 ALL PRIVILEGES 或 SUPER Super_priv 所有的权限名

列权限的权限类型

值只能指定为 SELECT、INSERT 和 UPDATE,同时权限的后面需要加上 列名 列表 column-list

用户权限类型

1
2
3
4
5
6
7
8
# 创建新的用户,并授予 数据有查询、插入权限,并授予 GRANT 权限
GRANT SELECT,INSERT SLAVE ON *.* TO 'slave'@'localhost' identified by '123456' WITH GRANT OPTION;

# 查询用户权限
SHOW GRANTS FOR 'slave'@'localhost';

# 刷新
FLUSH PRIVILEGES;

IPv4查看

cat /proc/net/sockstat

1
2
3
4
5
6
sockets: used 230
TCP: inuse 30 orphan 0 tw 2 alloc 36 mem 2
UDP: inuse 3 mem 0
UDPLITE: inuse 0
RAW: inuse 0
FRAG: inuse 0 memory 0

说明:

  • sockets: used:已使用的所有协议套接字总量
  • TCP: inuse:正在使用(正在侦听)的TCP套接字数量。其值≤ netstat –lnt | grep ^tcp | wc –l
  • TCP: orphan:无主(不属于任何进程)的TCP连接数(无用、待销毁的TCP socket数)
  • TCP: tw:等待关闭的TCP连接数。其值等于netstat –ant | grep TIME_WAIT | wc –l
  • TCP:alloc(allocated):已分配(已建立、已申请到sk_buff)的TCP套接字数量。其值等于netstat –ant | grep ^tcp | wc –l
  • TCP:mem:套接字缓冲区使用量(单位不详。用scp实测,速度在4803.9kB/s时:其值=11,netstat –ant 中相应的22端口的Recv-Q=0,Send-Q≈400)
  • UDP:inuse:正在使用的UDP套接字数量
  • RAW:
  • FRAG:使用的IP段数量

IPv6查看

cat /proc/net/sockstat6

1

TCP 报文格式简介

  • TCP 报文由 TCP HeaderTCP 数据组成。
  • TCP Header 的最大长度为 60 字节(byte),而必须要有的固定长度也就是图一的前5层的**20字节(byte),每层占有 32bit,也就是 32/8=4 字节,5层,5*4 = 20 字节,那么第六层的可选项和填充也就是Tcp Options字段最大为60-20=40字节(byte)**。填充是为了使TCP首部为4字节(32bit)的整数倍。

TCP首部格式

2964446-ab077ff3902529a3.webp

Source Port:源端口,16位(bit),2个字节(byte)。
Destination Port:目的端口,16位,2个字节。
Sequence Number:序号,发送数据包中的第一个字节的序列号,32位。
Acknowledgment Number:确认序列号,32位。
Data Offset:数据偏移,4位,该字段的值是TCP首部(包括选项)长度除以4。
标志位:6位,共6个标志位
URG 表示 Urgent Pointer 字段有意义
ACK 表示 Acknowledgment Number 字段有意义
PSH 表示 Push 功能,RST 表示复位 TCP 连接
RST 表示连接复位请求
SYN 表示 SYN 报文(在建立 TCP 连接的时候使用)
FIN 表示没有数据需要发送了(在关闭 TCP 连接的时候使用)
Window:窗口,表示接收缓冲区的空闲空间,16位,2个字节,用来告诉TCP连接对端自己能够接收的最大数据长度。
Checksum:校验和,16位,2个字节。
Urgent Pointers:紧急指针,16位,2个字节,只有 URG 标志位被设置时该字段才有意义,表示紧急数据相对序列号(Sequence Number字段的值)的偏移。
选项和填充:最常见的可选字段是最长报文大小,又称为 MSS(Maximum Segment Size),每个连接方通常都在通信的第一个报文段(为建立连接而设置SYN标志为1的那个段)中指明这个选项,它表示本端所能接受的最大报文段的长度。选项长度不一定是32位的整数倍,所以要加填充位,即在这个字段中加入额外的零,以保证TCP头是32的整数倍。
数据:TCP 报文段中的数据部分是可选的。在一个连接建立和一个连接终止时,双方交换的报文段仅有 TCP 首部。如果一方没有数据要发送,也使用没有任何数据的首部来确认收到的数据。在处理超时的许多情况中,也会发送不带任何数据的报文段。

TCP Options字段

Tcp Options 字段的最大长度为40字节。Tcp Options 字段的一般数据结构如图所示:

  • Kind(1字节)
  • Length(1字节)
  • Info(n字节)

选项的第一个字段 kind 说明选项的类型。有的 TCP 选项没有后面两个字段,仅包含1字节的kind字段。第二个字段length(如果有的话)指定该选项的总长度,该长度包括kind字段和length字段占据的2字节。第三个字段 info(如果有的话)是选项的具体信息。

tcpoptions.png

  • 第一个kind= 2,表示最大报文段长度(Max Segment Size,MSS),TCP 模块通常将 MSS 设置为(MTU-40, MTU[Maximum Transmission Unit,缩写 MTU,中文名是:最大传输单元])字节(减掉的这40字节包括20字节的TCP头部和20字节的IP头部)。这样携带 TCP 报文段的IP数据报的长度就不会超过 MTU(假设TCP头部和IP头部都不包含选项字段,并且这也是一般情况),从而避免本机发生IP分片。对以太网而言,MSS 值是1460(1500-40)字节。
  • kind= 4,表示支持 SACK,SACK Block(收到乱序数据)。
  • kind = 8,代表 Timestamps,即时间戳,启用 Timestamp Option 后,每个 TCP Segment 中都会带有 Timestamp Option,其中包含了两个 32bit 的 Timestamp 也就是各四个字节的 Timestamp Value(TSval)和 Timestamp Echo Reply(TSecr)。发送方在发送报文段时把当前时钟的时间值放入时间戳字段,接收方在确认该报文段时把时间戳字段值复制到时间戳回送回答字段。因此,发送方在收到确认报文后,可以准确计算出RTT。

TCP标志位

在TCP层,有个FLAGS字段,这个字段有以下几个标识:SYN, FIN, ACK, PSH, RST, URG。其中,对于我们日常的分析有用的就是前面的五个字段。

SYN表示建立连接,FIN表示关闭连接,ACK表示响应,PSH表示有 DATA数据传输,RST表示连接重置。

ACK是可能与SYN,FIN等同时使用的,比如SYN和ACK可能同时为1,它表示的就是建立连接之后的响应,如果只是单个的一个SYN,它表示的只是建立连接。
TCP的几次握手就是通过这样的ACK表现出来的。但SYN与FIN是不会同时为1的,因为SYN表示的是建立连接,而FIN表示的是断开连接。
RST一般是在FIN之后才会出现为1的情况,表示的是连接重置。
一般地,当出现FIN包或RST包时,我们便认为客户端与服务器端断开了连接;而当出现SYN和SYN+ACK包时,我们认为客户端与服务器建立了一个连接。
PSH为1的情况,一般只出现在DATA内容不为0的包中,也就是说PSH为1表示的是有真正的TCP数据包内容被传递。

SYN:同步标志

同步序列编号(Synchronize Sequence Numbers)栏有效,表示同步序号,用来建立连接。该标志仅在三次握手建立TCP连接时有效。它提示TCP连接的服务端检查序列编号,该序列编号为TCP连接初始端(一般是客户端)的初始序列编号。TCP序列编号是一个范围从 0~4294967295 (2^32-1) 的32位计数器。通过TCP连接交换的数据中每一个字节都经过序列编号。在TCP报头中的序列编号栏包括了TCP分段中第一个字节的序列编号。

SYN标志位和ACK标志位搭配使用,当连接请求的时候,SYN=1,ACK=0;连接被响应的时候,SYN=1,ACK= 1;

这个标志的数据包经常被用来进行端口扫描。扫描者发送一个只有SYN的数据包,如果对方主机响应了一个数据包回来,就表明这台主机存在这个端口;但是由于这种扫描方式只是进行TCP三次握手的第一次握手,因此这种扫描的成功表示被扫描的机器不很安全,一台安全的主机将会强制要求-连接-严格进行的TCP三次握手;

初始化序列号生成过程:

RFC1948中提出了一个较好的初始化序列号ISN随机生成算法。

ISN = M + F(localhost, localport, remotehost, remoteport).
M是一个计时器,这个计时器每隔4毫秒加1。
F是一个Hash算法,根据源IP、目的IP、源端口、目的端口生成一个随机数值。要保证hash算法不能被外部轻易推算得出,用MD5算法是一个比较好的选择。
ISN会和一个假的时钟绑在一起,这个时钟M会在每4微秒对ISN做加一操作,直到超过 2^32,又从0开始。这样,一个ISN的周期大约是4.55个小时。因为,我们假设我们的TCP Segment在网络上的存活时间不会超过Maximum Segment Lifetime(缩写为MSL),所以,只要MSL的值小于4.55小时,那么,我们就不会重用到ISN。

ACK:确认标志

确认编号(Acknowledgement Number)栏有效。此标志表示应答域有效;有两个取值:0和1,为1的时候表示应答域有效,反之为0。TCP报头内的确认编号栏内包含的确认编号(w+1,Figure-1)为下一个预期的序列编号,同时提示远端系统已经成功接收所有数据。

RST:复位标志

这个标志表示连接复位请求。用来复位那些产生错误的连接,也被用来拒绝错误和非法的数据包;

URG:紧急标志

此标志表示TCP包的紧急指针域有效,用来保证TCP连接不被中断,并且督促中间层设备要尽快处理这些数据;

PSH:推标志

这个标志位表示Push操作,该标志置位时,指在数据包到达接收端以后,接收端不将该数据进行队列处理,立即传送给应用程序,而不是在缓冲区中排队。在处理 telnet 或 rlogin 等交互模式的连接时,该标志总是置位的。

FIN:结束标志

表示发送端已经达到数据末尾,也就是说双方的数据传送完成,没有数据可以传送了,发送FIN标志位的TCP数据包后,连接将被断开。这个标志的数据包也经常被用于进行端口扫描。当一个FIN标志的TCP数据包发送到一台计算机的特定端口,如果这台计算机响应了这个数据,并且反馈回来一个RST标志 的TCP包,就表明这台计算机上没有打开这个端口,但是这台计算机是存在的;如果这台计算机没有反馈回来任何数据包,这就表明,这台被扫描的计算机存在这个端口。

工作方式

建立连接

tcp1

TCP是因特网中的传输层协议,使用三次握手协议建立连接。当主动方发出 SYN 连接请求后,等待对方回答 SYN+ACK,并最终对对方的 SYN 执行 ACK 确认。

TCP三次握手的过程如下:

  • 客户端发送 SYN(SEQ=x) 报文给服务器端,进入 SYN_SEND 状态。
  • 服务器端收到 SYN 报文,回应一个 SYN (SEQ=y)ACK(ACK=x+1) 报文,进入 SYN_RECV 状态。
  • 客户端收到服务器端的 SYN 报文,回应一个 ACK(ACK=y+1) 报文,进入 Established(已获确认的) 状态。

三次握手完成,TCP客户端和服务器端成功地建立连接,可以开始传输数据了。

连接终止

tcp3.gif

建立一个连接需要三次握手,而终止一个连接要经过四次握手,这是由TCP的 半关闭half-close)造成的。

  • (1)某个应用进程首先调用 close,称该端执行 主动关闭(active close)。该端的TCP于是发送一个 FIN 分节,表示数据发送完毕。
  • (2) 接收到这个 FIN 的对端执行 被动关闭(passive close),这个 FIN 由TCP确认。

注意:FIN 的接收也作为一个文件结束符(end-of-file)传递给接收端应用进程,放在已排队等候该应用进程接收的任何其他数据之后,因为,FIN 的接收意味着接收端应用进程在相应连接上再无额外数据可接收。

  • (3) 一段时间后,接收到这个文件结束符的应用进程将调用 close 关闭它的套接字。这导致它的 TCP 也发送一个 FIN
  • (4) 接收这个最终 FIN 的原发送端TCP(即执行主动关闭的那一端)确认这个 FIN

既然每个方向都需要一个FIN和一个 ACK ,因此通常需要4个分节。

注意:
(1) 通常 是指,某些情况下,步骤1的 FIN 随数据一起发送,另外,步骤2和步骤3发送的分节都出自执行被动关闭那一端,有可能被合并成一个分节。
(2) 在 步骤2 与 步骤3 之间,从执行 被动关闭一端 到 执行主动关闭一端 流动数据是可能的,这称为 半关闭(half-close)。
(3) 当一个Unix进程无论自愿地(调用exit或从main函数返回)还是非自愿地(收到一个终止本进程的信号)终止时,所有打开的描述符都被关闭,这也导致仍然打开的任何TCP连接上也发出一个FIN
无论是客户还是服务器,任何一端都可以执行主动关闭。通常情况是,客户执行主动关闭,但是某些协议,例如,HTTP/1.0却由服务器执行主动关闭。

TCP重连

tcp重连.png

四元组:源IP地址、目的IP地址、源端口、目的端口
五元组:源IP地址、目的IP地址、协议号、源端口、目的端口
七元组:源IP地址、目的IP地址、协议号、源端口、目的端口、服务类型、接口索引

状态详解

  1. CLOSED:表示初始状态。

  2. LISTEN:表示服务器端的某个SOCKET处于监听状态,可以接受连接了。

  3. SYN_RCVD: 这个状态表示接受到了SYN报文,在正常情况下,这个状态是服务器端的SOCKET在建立TCP连接时的三次握手会话过程中的一个中间状态,很短暂,基本 上用netstat你是很难看到这种状态的,除非你特意写了一个客户端测试程序,故意将三次TCP握手过程中最后一个ACK报文不予发送。因此这种状态 时,当收到客户端的ACK报文后,它会进入到ESTABLISHED状态。

  4. SYN_SENT: 这个状态与SYN_RCVD呼应,当客户端SOCKET执行CONNECT连接时,它首先发送SYN报文,因此也随即它会进入到了SYN_SENT状态,并等待服务端的发送三次握手中的第2个报文。SYN_SENT状态表示客户端已发送SYN报文。

  5. ESTABLISHED:表示连接已经建立了。

  6. FIN_WAIT_1: FIN_WAIT_1和FIN_WAIT_2状态的真正含义都是表示等待对方的FIN报文。而这两种状态的区别 是:FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHED状态时,它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET即 进入到FIN_WAIT_1状态。而当对方回应ACK报文后,则进入到FIN_WAIT_2状态,当然在实际的正常情况下,无论对方何种情况下,都应该马 上回应ACK报文,所以FIN_WAIT_1状态一般是比较难见到的,而FIN_WAIT_2状态还有时常常可以用netstat看到。

  7. FIN_WAIT_2:FIN_WAIT_2状态下的SOCKET,表示半连接,也即有一方要求close连接,但另外还告诉对方,我暂时还有点数据需要传送给你,稍后再关闭连接。

  8. TIME_WAIT: 表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。如果FIN_WAIT_1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。

  9. CLOSING: 这种状态比较特殊,实际情况中应该是很少见,属于一种比较罕见的例外状态。正常情况下,当你发送FIN报文后,按理来说是应该先收到(或同时收到)对方的 ACK 报文,再收到对方的 FIN 报文。但是 CLOSING 状态表示你发送 FIN 报文后,并没有收到对方的ACK报文,反而却也收到了对方的FIN报文。什 么情况下会出现此种情况呢?其实细想一下,也不难得出结论:那就是如果双方几乎在同时close一个SOCKET的话,那么就出现了双方同时发送FIN报 文的情况,也即会出现CLOSING状态,表示双方都正在关闭SOCKET连接。

  10. LAST_ACK:它是被动关闭一方在发送FIN报文后,最后等待对方的ACK报文。当收到ACK报文后,也即可以进入到CLOSED可用状态了。

参考:

Tcp报文简介以及头部选项字段(Tcp Options字段)

常用的TCP Option

TCP协议中的序列号

TCP标志位详解

浅析TCP中时间戳选项timestamp

简介

TcpDump 使用了独立于系统的 libpcap 的接口。libpcap 是linux平台下的网络数据包捕获函数包,大多数网络监控软件都以它为基础。tcpdump 调用libpcap 的接口在 linux 系统链路层抓包。而linux本身指定的许多访问控制规则都是基于三层或三层以上的过滤规则,所以 tcpdump 可以抓取过滤规则之前的数据包。使用tcpdump 需要有root权限。

网卡基础知识

网卡的不同接受模式

  • 广播模式:该模式下网卡能接收网络中的广播信息。
  • 组播模式:该模式下网卡能接收网络中的组播信息。
  • 直接模式:该模式下网卡能接收网络中目的地址为自己的数据包。
  • 混杂模式:该模式下网卡能接收网络中一切通过该网卡的数据包。

注:网卡混杂模式:是网卡的一种工作模式,一般在抓取网卡数据包时使用。

1
2
3
4
device eth0 entered promiscuous mode # 是指网卡 eth0 进入了混杂模式。
device eth0 left promiscuous mode # 网卡 eth0 离开了混杂模式。
ifconfig eth0 promisc # 设置网卡eth0为混杂模式
ifconfig eth0 -promisc # 取消网卡eth0的混杂模式

网络中数据包的分类

  • 广播包:指IP子网内广播的数据包。适用范围较小只在本地子网有效。通过路由器和网络设备控制传输。
  • 单播包:发送者和每一接受者中点对点的网络连接。
  • 组播包:借助组播路由协议建立树形路由,在尽可能远的分岔路口才开始复制和奋发。(224.0.0.0~224.0.0.255是预留的组播地址)

数据包接收流程

  • 网卡收到数据包,获取数据包中的目的MAC地址。
  • 根据网卡驱动设置的网卡接受模式去判断是否接受该数据。
  • 若接受该数据:发出中断信号通知CPU;CPU收到中断信号后根据发出该中断信号的网卡驱动程序的网卡驱动程序地址调用网卡驱动程序;网卡驱动程序处理数据;驱动程序将数据放入信号堆栈;系统接触到数据。
  • 若不接受该数据:网卡直接丢弃该数据;系统不会接触到数据。

安装

1
2
3
4
5
6
# 解锁
# 如果不解锁,可能造成错误:Couldn't find user 'tcpdump'
chattr -i /etc/passwd /etc/shadow /etc/group /etc/gshadow

# 安装
yum install tcpdump

tcpdump命令格式

1
2
tcpdump [ -DenNqvX ] [ -c count ] [ -F file ] [ -i interface ] [ -r file ]
[ -s snaplen ] [ -w file ] [ expression ]
  • -a 尝试将网络和广播地址转换成名称。
  • -c<数据包数目> 收到指定的数据包数目后,就停止进行倾倒操作。
  • -d 把编译过的数据包编码转换成可阅读的格式,并倾倒到标准输出。
  • -dd 把编译过的数据包编码转换成C语言的格式,并倾倒到标准输出。
  • -ddd 把编译过的数据包编码转换成十进制数字的格式,并倾倒到标准输出。
  • -e 在每列倾倒资料上显示连接层级的文件头。
  • -f 用数字显示网际网络地址。
  • -F<表达文件> 指定内含表达方式的文件。
  • -i<网络界面> 使用指定的网络截面送出数据包。
  • -l 使用标准输出列的缓冲区。
  • -n 不把主机的网络地址转换成名字。
  • -N 不列出域名。
  • -O 不将数据包编码最佳化。
  • -p 不让网络界面进入混杂模式。
  • -q 快速输出,仅列出少数的传输协议信息。
  • -r<数据包文件> 从指定的文件读取数据包数据。
  • -s<数据包大小> 设置每个数据包的大小。
  • -S 用绝对而非相对数值列出TCP关联数。
  • -t 在每列倾倒资料上不显示时间戳记。
  • -tt 在每列倾倒资料上显示未经格式化的时间戳记。
  • -T<数据包类型> 强制将表达方式所指定的数据包转译成设置的数据包类型。
  • -v 详细显示指令执行过程。
  • -vv 更详细显示指令执行过程。
  • -vvv:产生比-vv更详细的输出。
  • -x 用十六进制字码列出数据包资料。
  • -w<数据包文件> 把数据包数据写入指定的文件。

常用实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 监听特定主机
tcpdump host 182.254.38.55

# 特定来源
tcpdump src host hostname

# 特定目标地址
tcpdump dst host hostname

# 特定端口
tcpdump port 3000

# 监听TCP/UDP
tcpdump tcp

# 来源主机+端口+TCP
# 监听来自主机 10.207.22.254 在端口 8011 上的TCP数据包
tcpdump tcp port 8011 and src host 10.207.22.254

# 监听特定主机之间的通信
tcpdump ip host 210.27.48.1 and 210.27.48.2

# 保存到本地
# 备注:tcpdump 默认会将输出写到缓冲区,只有缓冲区内容达到一定的大小,或者tcpdump退出时,才会将输出写到本地磁盘
tcpdump -n -vvv -c 1000 -w /ldjc/data.pcap

输出

TCP协议行的典型格式如下:

[Timestamp] [Protocol] [Src IP].[Src Port] > [Dst IP].[Dst Port]: [Flags], [Seq], [Ack], [Win Size], [Options], [Data Length]

让我们逐个字段进行说明,并解释以下内容:

1
2
21:53:20.460144 IP 192.168.182.166.57494 > 35.222.85.5.80: Flags [P.], seq 1:88, ack 1, win 29200,  
options [nop,nop,TS val 1067794587 ecr 2600218930], length 87
1
2
3
4
5
21:53:20.460144 - 捕获的数据包的时间戳为本地时间,并使用以下格式:hours:minutes:seconds.frac,
其中frac是自午夜以来的几分之一秒。
IP - 分组协议。 在这种情况下,IP表示Internet协议版本4(IPv4)。
192.168.182.166.57494 - 源IP地址和端口,以点(.)分隔。
35.222.85.5.80 - 目的IP地址和端口,以点号(.)分隔。

TCP 标志字段。 在此示例中,[P.] 表示推送确认数据包,用于确认前一个数据包并发送数据。 其他典型标志字段值如下:

1
2
3
4
5
6
[.] - ACK (Acknowledgment)
[S] - SYN (Start Connection)
[P] - PSH (Push Data)
[F] - FIN (Finish Connection)
[R] - RST (Reset Connection)
[S.] - SYN-ACK (SynAcK Packet)
1
2
3
4
5
6
7
8
9
seq 1:88 - 序列号在first:last表示法中。 它显示了数据包中包含的数据数量。 
除了数据流中的第一个数据包(其中这些数字是绝对的)以外,所有后续数据包均用作相对字节位置。
在此示例中,数字为1:88,表示此数据包包含数据流的字节1至88。 使用-S选项可打印绝对序列号。
ack 1 - 确认号(acknowledgment number)是此连接另一端所期望的下一个数据的序列号。
win 29200 - 窗口号是接收缓冲区中可用字节的数目。
options [nop,nop,TS val 1067794587 ecr 2600218930] - TCP选项。
使用 nop 或 “ no operation” 填充使TCP报头为4字节的倍数。
TS val 是TCP时间戳,而 ecr 表示回显应答。 请访问 IANA 文档以获取有关 TCP 选项的更多信息。
length 87 - 有效载荷数据的长度

参考:

tcpdump抓包wireshark分析

一文搞定tcpdump基本用法

Linux下抓包命令tcpdump详解

Linux基础:用tcpdump抓包

聊聊 tcpdump 与 Wireshark 抓包分析

0%