TCP标志位

  •  

     

  •  

     

  •  

     

     

     

     

    第一次握手:客户端发送SYN包至服务器,并进入SYN_SENT状态,等待服务器确认

    第二次握手:服务器收到客户端的SYN包,发送一个ACK,同时发送自己的SYN,此时服务器进入SYN_RCVD状态

    第三次握手:客户端接收到服务器发送的SYN+ACK后,进入ESTABLISHED状态,并发送服务器SYN包的确认ACK,服务器接收到客户端ACK后,进入ESTABLISHED状态

    当客户端和服务器都进入ESTABLISHED状态后,客户端和服务器之间就可以开始双向传递数据了。

    •  

       


  • FIN是客户端或服务器正常关闭tcp连接发的包,发送缓冲区Send-Q数据发完才会发FIN
  • RST是客户端或服务器异常关闭tcp连接发的包,通常都是主机收到不存在的tcp通道的tcp报文,主机“被迫”回复RST告知对方tcp连接异常,收到RST的一方就会关闭这个socket,释放所有socket信息,且不会回复ACK
“TCP首部字段有6个是flags,每个标志位有特殊的含义,它们可以单独存在,也可以同时存在。对于接收方,不同的标志位代表不同的意思,需要做正确的处理

 

Client -> SYN, SEQ=100
Client <- SYN, ACK, SEQ=700, ACK=101 <- Server
Client -> ACK = 701, SEQ=101 [50 Bytes of data]
Client -> ACK = 701 [Again, didn't receive sth from server yet], SEQ = 151

 其实在握手和结束时确认号应该是对方序列号加1,传输数据时则是对方序列号加上对方携带应用层数据的长度.
另外,如果对方没有数据过来,则自己的确认号不变,序列号为上次的序列号加上本次应用层数据发送长度.

seq是序列号,就是data stream字节序号这是为了连接以后传送数据用的,ack是对收到的数据包的确认,值是等待接收的数据包的序列号。都是字节
在第一次消息发送中,A随机选取一个序列号作为自己的初始序号发送给B;第二次消息B使用ack对A的数据包进行确认,因为已经收到了序列号为x的数据包,准备接收序列号为x+1的包,所以ack=x+1,同时B告诉A自己的初始序列号,就是seq=y;第三条消息A告诉B收到了B的确认消息并准备建立连接,A自己此条消息的序列号是x+1,所以seq=x+1,而ack=y+1是表示A正准备接收B序列号为y+1的数据包。
seq是数据包本身的序列号;ack是期望对方继续发送的那个数据包的序列号。

ack和seq都是两个整型变量,表示序列号;ACK、SYN是指标志位,是用来标识这个包的类型的,这两者不是同一个东西。

 

 

1:SYN/ACK:即序列号与确认号,允许连接的双方在发送数据时,同时对对方的数据段进行确认

1) SYN:数据包都是按字节编号,如果前一个数据包的序列号是0而该数据段的数据区携带了100B,则下一个数据包的序列号应该是100;初始序列号必须是随机产生的,这个值在建立连接的过程中指定

注意:下一个数据包指的是本机下一次向对方发送的数据包,并不包括对方回复的数据包

2) ACK:确认收到的数据段的序列号,表示它准备接受的下一个数据包的序列号

举一个例子: Client与Server通信

三次握手建立连接

1) Client发起连接,初始序列号假设为x,则SEQ=X+0,此时ACK并不置位

2) Server进行回复,ACK位置1,且ACK=X+1(表明下一个要接收的数据包的序列号),同时发送自己的初始序列号Y

3) Client进行确认,ACK位置1,且ACK=Y+1(表明下一个要接收的数据包的序列号),同时自己的序列号为SEQ=X+1;由于这里TCP数据包并没有长度,所以下一次发送的数据包SEQ仍然为X+1

接下来Client给Server发送数据包

4) 假设数据包长度为256,则SEQ=X+1,ACK=Y+1,且data length=256

5) Server进行回复,SEQ=Y+1,ACK=X+257(表明下一个要接收的数据包的序列号)

 

2:滑动窗口机制:简单的确认重发机制(发送方发出一个数据后就停下来等待对方的确认)效率低下——让发送方可以连续发送多个数据,然后等待接收方的确认

1) TCP数据根据状态划分为三种类型:已发送、待发送以及发送中

2) 窗口的大小决定了数据传输的效率,需要根据网络实时情况来决定其大小

 

——TCP的滑动窗口机制:基本的数据单位不是数据段,而是字节;每个窗口用三个指针表示,第一个指向窗口的第一个字节,第二个指向窗口中马上要发送的字节,第三个指向窗口的最后一个字节。

1) 累积确认:接收方对某个编号进行确认,该编号之前的数据必须都已接收到了,从而有时候前面窗口的数据没有接受到,就必须暂存数据,并在接收到前面的其他数据后进行累积确认

a) 优点:允许发送方在对数据进行重发时发送更多的数据,无需对丢失的确认进行重发;为确认数据段也会丢失,但只要下一个确认能够到达对方就无需对前一个确认进行重发

b) 缺点:若第一个窗口的数据丢失,则收到的确认好一直都是关于之前数据的确认,得不到关于新发送的数据包的确认;从而无法确定从该窗口开始的数据包哪些成功发送,哪些丢失了

2) 发送方窗口不能大于接收方窗口,凡是ACK 置为1 的数据段都应该将自己接收窗口的当前大小填入TCP数据段头部的窗口字段中,通知给发送方

3) 拥塞控制机制:慢启动和成倍减少;TCP 协议实际发送窗口的大小应该是拥塞窗口接收方接收窗口中小的一个

a) 成倍减少机制:当TCP 发现数据段丢失(即超时重发)时,就将拥塞窗口的大小减少一半(但其大小至少应为1 ) ,对于减小窗口后仍在发送窗口中的数据段,将其重发的超时值延长一倍。

b) 慢启动机制:在TCP 启动一个新的连接或拥塞结束后,将拥塞窗口的大小设置为一个数据段的大小,然后每收到一个确认段,TCP 就将拥塞窗口的大小增加一个数据段;在拥塞发生并恢复后,通过慢启动机制使得拥塞窗口的大小达到了拥塞之前的一半,TCP 就启动一个拥塞避免机制以减缓窗口扩大的速度

4) 傻窗口症状:极端的情况,接收方的应用程序一直没有处理接收到的数据,这样接收方的TCP 缓冲区都被接收到的数据占满,接收窗口的大小减小为0,TCP 将这个窗口大小通知给发送方TCP,这时整个数据传输就停下来了

Flags

可以在点击以太网报文结构查看各协议层协议首部字段及其含义

TCP协议首部格式

上图标注的红圈里有6个标志位,每个标志位占用一个比特

URG

“紧急指针有效标识。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)

ACK

“确认序号有效标识。只有当ACK=1时确认号字段才有效。当ACK=0时,确认号无效

PSH

“标识接收方应该尽快将这个报文段交给应用层。接收到PSH = 1的TCP报文段,应尽快的交付接收应用进程,而不再等待整个缓存都填满了后再向上交付

RST

“重建连接标识。当RST=1时,表明TCP连接中出现严重错误(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立连接

SYN

“同步序号标识,用来发起一个连接。SYN=1表示这是一个连接请求或连接接受请求

FIN

“发端完成发送任务标识。用来释放一个连接。FIN=1表明此报文段的发送端的数据已经发送完毕,并要求释放连接

RST

RST

“Reset,复位标志,用于非正常地关闭连接。它是TCP协议首部里的一个标志位。发送RST包关闭连接时,直接丢弃缓冲区的包发送RST包(这个和发FIN包不同)。而接收端收到RST包后,也不必发送ACK包来确认

如何触发

正常地关闭连接用FIN标志位,但FIN标志位不能用来处理异常情况

举例

客户端和服务器TCP连接正常,突然服务器掉电重启,与客户端的TCP连接状态由于掉电而完全消失。之后,客户端发给服务器任何消息,都会触发服务器发RST作为回应。服务器之所以发RST,是因为连接不存在,通过Reset状态位,间接告诉客户端异常情况的存在。如果Reset顺利到达客户端,客户端意识到异常发生了,会立马释放该TCP连接所占用的内存资源(状态、数据)、以及端口号,且不会回复ACK

连接未监听的端口

连接一个未监听的端口,则被连接方会发送一个RST。也就是说主机传输层TCP程序接收到一个SYN包,而这个SYN包目的端口并没有socket监听,那么主机的协议栈会直接回复一个RST

目的主机或网络路径中的防火墙拦截

如果目的主机或者网络路径中显式的设置了对数据包的拦截

使用iptables对主机的防火墙添加了一条规则,对于目的端口是60000的TCP报文,丢弃并回复RST

socket接收缓冲区Recv-Q中的数据未完全被应用程序读取时关闭该socket

接收到的数据缓存在缓冲区Recv-Q,它们等待被上层应用取走,如果缓冲区Recv-Q有数据未被应用取走,而此时调用了socket.close()方法强行关闭TCP连接,那么TCP协议程序发送的就不是FIN,而是RST

向已关闭的socket发送数据

顾名思义,主机传输层TCP协议程序接收到一条TCP数据报,而目的端口并没有socket监听,那么主机的协议栈会直接回复一个RST

向已关闭的连接发送FIN

主机传输层TCP协议程序接收到一条FIN,而目的端口并没有socket监听,那么主机的协议栈会直接回复一个RST

向已经消逝的连接中发送数据

和上面的举例相同

请求超时后收到回复

主机创建socket,设置SO_RCVTIMEOUT选项为100ms,向对端发送SYN,过了100ms后才收到ACK+SYN,那么主机的协议栈会直接回复一个RST

SO_LINGER

socket设置SO_LINGER选项,socket调用close()函数时,会直接丢弃缓冲区Send_Q未发完的数据,并发送RST

Linux下启用TIME_WAIT快速回收

修改/etc/sysctl.conf中内核参数: net.ipv4.tcp_tw_recycle = 1 当收到的SYN包的timestamp比上次的小时,就会发RST

TCP socket在任何状态下,只要收到RST包,即可进入CLOSED初始状态,不会有任何回应。至于是否通知上层应用,要根据应用程序是阻塞模式还是非阻塞模式:

阻塞模型下,内核无法主动通知应用层出错,只有应用层主动调用read()或者write()这样的IO系统调用时,内核才会利用出错来通知应用层对端RST

非阻塞模型下,select或者epoll会返回sockfd可读,应用层对其进行读取时,read()会报错RST

TCP标志位 
URG:此标志表示TCP包的紧急指针域(后面马上就要说到)有效,用来保证TCP连接不被中断,并且督促中间层设备要尽快处理这些数据;
ACK:此标志表示应答域有效,就是说前面所说的TCP应答号将会包含在TCP数据包中;有两个取值:0和1,为1的时候表示应答域有效,反之为0;
 
PSH:这个标志位表示Push操作。所谓Push操作就是指在数据包到达接收端以后,立即传送给应用程序,而不是在缓冲区中排队;
 
RST:这个标志表示连接复位请求。用来复位那些产生错误的连接,也被用来拒绝错误和非法的数据包;
 
SYN:表示同步序号,用来建立连接。SYN标志位和ACK标志位搭配使用,当连接请求的时候,SYN=1,ACK=0;连接被相应的时候,SYN=1,ACK=1;这个标志的数据包经常被用来进行端口扫描。扫描者发送一个只有SYN的数据包,如果对方主机响应了一个数据包回来 ,就表明这台主机存在这个端口;但是由于这种扫描方式只是进行TCP三次握手的第一次握手,因此这种扫描的成功表示被扫描的机器不很安全,一台安全的主机将会强制要求一个连接严格的进行TCP的三次握手;
 
FIN:表示发送端已经达到数据末尾,也就是说双方的数据传送完成,没有数据可以传送了,发送FIN标志位的TCP数据包后,连接将被断开。这个标志的数据包也经常被用于进行端口扫描。当一个FIN标志的TCP数据包发送到一台计算机的特定端口,如果这台计算机响应了这个数据,并且反馈回来一个RST标志的TCP包,就表明这台计算机上没有打开这个端口,但是这台计算机是存在的;如果这台计算机没有反馈回来任何数据包,这就表明,这台被扫描的计算机不存在。
 
需要说明的是,金山网镖的日志报告使用的不是这些标志位的全称,而是使用的这些标志位的首字母,比如拦截到一个包含FIN标志的TCP数据包将会报告x.x.x.x的TCP数据包:F。还有一点,你的日志可能报告x.x.x.x的TCP数据包:NULL,这是什么?NULL标明发送给你的数据包不包含任何标志位,你收到这种数据包,很多情况下意味着你被扫描,扫描者发送NULL数据包给你,如果你的计算机发送回去了一个FIN标志的TCP数据包,就表明他探测的端口在你的计算机上不存在,但是你的计算机就已经被确定存在了,这样他就可以使用其他的扫描方式进行端口探测。有一些特殊的扫描方式可以绕过不严谨的防火墙。
 
了解到了TCP标志位的含义,就可以了解TCP的三次握手是怎么进行的了:发送端发送一个SYN=1,ACK=0标志的数据包给接收端,请求进行连接,这是第一次握手;接收端收到请求并且允许连接的话,就会发送一个SYN=1,ACK=1标志的数据包给发送端,告诉它,可以通讯了,并且让发送端发送一个确认数据包,这是第二次握手;最后,发送端发送一个SYN=0,ACK=1的数据包给接收端,告诉它连接已被确认,这就是第三次握手。之后,一个TCP连接建立,开始通讯。
posted @ 2021-09-02 09:30  *Tesla*  阅读(87)  评论(0)    收藏  举报
       [00:00.000] 作词 : 陈信荣
    [00:01.000] 作曲 : 周传雄
    [00:02.000] 编曲 : 周传雄
    [00:03.000] 制作人 : 周传雄
    [00:29.259]过完整个夏天
    [00:34.742]忧伤并没有好一些
    [00:41.185]开车行驶在公路无际无边
    [00:47.320]有离开自己的感觉
    [00:52.453]
    [00:53.347]唱不完一首歌
    [00:59.370]疲倦还剩下黑眼圈
    [01:05.596]感情的世界伤害在所难免
    [01:11.703]黄昏再美终要黑夜
    [01:18.292]依然记得从你口中说出再见坚决如铁
    [01:24.732]昏暗中有种烈日灼身的错觉
    [01:30.171]黄昏的地平线
    [01:33.230]划出一句离别
    [01:36.313]爱情进入永夜
    [01:42.165]
    [01:42.881]依然记得从你眼中滑落的泪伤心欲绝
    [01:49.290]混乱中有种热泪烧伤的错觉
    [01:54.774]黄昏的地平线
    [01:57.816]割断幸福喜悦
    [02:00.915]相爱已经幻灭
    [02:07.171]
    [02:19.647]唱不完一首歌
    [02:25.497]疲倦还剩下黑眼圈
    [02:31.753]感情的世界伤害在所难免
    [02:37.881]黄昏再美终要黑夜
    [02:42.994]
    [02:44.363]依然记得从你口中说出再见坚决如铁
    [02:50.872]昏暗中有种烈日灼身的错觉
    [02:56.291]黄昏的地平线
    [02:59.393]划出一句离别
    [03:02.507]爱情进入永夜
    [03:08.340]
    [03:09.205]依然记得从你眼中滑落的泪伤心欲绝
    [03:15.531]混乱中有种热泪烧伤的错觉
    [03:20.937]黄昏的地平线
    [03:23.991]割断幸福喜悦
    [03:27.025]相爱已经幻灭
    [03:34.375]
    [03:58.563]依然记得从你口中说出再见坚决如铁
    [04:04.694]昏暗中有种烈日灼身的错觉
    [04:10.141]黄昏的地平线
    [04:13.156]划出一句离别
    [04:16.228]爱情进入永夜
    [04:21.297]
    [04:22.863]依然记得从你眼中滑落的泪伤心欲绝
    [04:29.401]混乱中有种热泪烧伤的错觉
    [04:34.714]黄昏的地平线
    [04:37.774]割断幸福喜悦
    [04:40.913]相爱已经幻灭
    [05:39.200] 配唱制作人 : 吴佳明
    [05:39.533] 钢琴 : 周传雄
    [05:39.866] 吉他 : 许华强
    [05:40.199] 鼓 : Gary Gideon
    [05:40.532] 贝斯 : Andy Peterson
    [05:40.865] 弦乐编写 : 吴庆隆
    [05:41.198] 弦乐 : 孔朝晖/顾文丽/隋晶晶/梁中枢/尹淑占/王言/关旗
    [05:41.531] 和声编写 : 周传雄
    [05:41.864] 和声 : 周传雄
    [05:42.197] 录音师 : 林世龙/沈文钏/Geoffrey Lee
    [05:42.530] 混音师 : 王晋溢
    [05:42.863] 录音室 : 强力/HASAYAKE/Atomic & Audioplex (Singapore)
    [05:43.196] 混音室 : 白金
    [05:43.529] OP : Sony/ATV Music Publishing Taiwan/哈萨雅琪有限公司
    [05:43.862] SP : Sony/ATV Music Publishing Taiwan​