三次握手理解

1. 基本概念

  a)  TCP/IP 网络协议。

  TCP/IP 是由 OSI 7层解析简化而来,我们不需要知道OSI,只需要记牢TCP/IP 4 层即可。

   

  b)  组包流程

  如下图所示: 原始数据由应用层传递给传输层,传输层给其添加TCP或则UDP报头(端口号), 添加TCP/UDP报头的数据传递给网络层,添加IP报头(IP),然后由网络层传递给数据链路层添加以太网头和尾(MAC)

   

  c) IP 报文头结构

   

  Version: 表示这个IP数据包的版本,例如IPV4 或者IPV6

  IHL: Internet Head Length 告知这个IP报文头的长度

  Type of Service: 这个内容为 PPPDTRUU,代表这个数据包的服务类型:

         PPP: 代表包的优先级

         D: 0 代表一般延迟, 1代表低延迟

         T: 0 代表一般传输量, 1代表高传输量

         R: 0 代表一般可靠度, 1代表高可靠度

        UU: revered

  TotalLength: 指出该数据包的总大小, 包括报头以及数据. 最大为 65535 bytes

  Identitfication: 识别码, 当IP数据包足够大被分成了若干个小的IP数据包, 该字段区分是否不同的小的IP数据包是否来自同一个大的数据包。

  Flags: 内容为0DM:

         D: 0 代表可以分段, 1代表不能分段

         M: 0 代表此IP为最后分段, 1代表非最后分段。

  Fragment Offset: 分段偏移

         代表当前IP分段在原始的IP数据包中所占的位置, 类似于序号, 通过以上4字段 TotalLength, entitfication, Flags, Fragment Offset 就能将小的IP分段组合起来。

  Time To Live: TTL 生存时间, 范围为 0 – 255.

  Protocol Number: 协议代码, 通过协议代码,确定协议名称:

   

  IP TCP UDP 是常见的。

  Header Checksum: 校验值

  Source Address: 源地址的IP

  Destionation Address: 目标地址的IP

  Options: 其他参数

  Padding: 32bits对齐

  d) TCP 报文头:

   

  Source Port: 源端口

  Destionation: 目标端口

  Sequence Number: 数据包序号

  Acknowledge Number: 回应序号

  Data Offset: 数据补偿, 长度不固定

  Reserved: 未使用

  Code: Control Flag 控制标志码,代表连接状态,非常重要。共有6个bits. 分别说明如下:

  URG(Urgent): 1 代表此数据包为紧急数据包

  CK(Acknowledge): 1 代表这个数据包为响应数据包

  PSH(push fucntion): 1 代表要求对方立刻往上抛数据, 而不是等缓冲区满了再抛数据。

  RST(Reset): 1 代表连接马上结束, 并且无需等待对方确认。意思就是强制断线。

  SYN(Synchronous): 1 代表发送端希望双方能建立连接, SYN 通常带有”主动”的含义。

  FIN(finish): 1 代表传送结束, 与RST 的区别在于,RST 是很粗暴的”我断了,你随意”, 但是FIN 就代表“请问我可以断开了吗?”

  Window: 滑动窗口,用于通知对方本机的缓冲区的大小, 当window=0,代表缓冲区满了。

  Checksum:校验码

  Urgent Pointer:紧急字段, 只用code中的URG=1才有效。告知紧急数据所在的位置。

  Options: 表示可以接受最大数据段的容量,较少使用。

  Padding: 32bits对齐字段。

 

  e) 三次握手基本概念

  1) 为什么TCP协议有三次握手,而UDP协议没有?

    因为三次握手的目的是在client端和server端建立可靠的连接。保证双方发送的数据对方都能接受到,这也是TCP协议的被称为可靠的数据传输协议的原因。而UDP就不一样,UDP不提供可靠的传输模式,发送端并不需要得到接收端的状态,因此UDP协议就用不着使用三次握手。

  2)  3次握手的原理?

  3)  实际抓包分析:

  我在笔记本上搭建了HTTP服务器, 在本地使用Chrome 通过IP加端口的形式访问, 我们知道HTTP是基于TCP协议。如果访问成功,则一定经过了三次握手的过程。我们在命令行使用tcpdump进行抓包, 来进行我们的分析, 如下图所示(请注意, 我是在server端进行监听):

   

  我将关键部分抓出来:

  Tcpdump 指令:  sudo tcpdump tcp port 8008   -X

  第一个包:

  listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes

  21:48:22.317841 IP DESKTOP-8TIBRLB.local.63492 > yangxiaoyu-HP-EliteBook-8460p.local.8008: Flags [S], seq 524159038, win 8192, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0

       0x0000:  4500 0034 2c2e 4000 4006 68c3 c0a8 120f   E..4,.@[email protected].....

       0x0010:  c0a8 1273 f804 1f48 1f3e 083e 0000 0000    ...s...H.>.>....

       0x0020:  8002 2000 6a74 0000 0204 05b4 0103 0308  ....jt..........

       0x0030:  0101 0402    

  第二个包:

  21:48:22.317916 IP yangxiaoyu-HP-EliteBook-8460p.local.8008 > DESKTOP-8TIBRLB.local.63492: Flags [S.], seq 2434712356, ack 524159039, win 29200, options [mss 1460,nop,nop,sackOK,nop,wscale 7], length 0

        0x0000:  4500 0034 0000 4000 4006 94f1 c0a8 1273   E..4..@[email protected]

        0x0010:  c0a8 120f 1f48 f804 911e c324 1f3e 083f     .....H.....$.>.?

        0x0020:  8012 7210 a5f9 0000 0204 05b4 0101 0402   ..r.............

       0x0030:  0103 0307                                ....

  第三个包:

  21:48:22.319051 IP DESKTOP-8TIBRLB.local.63492 > yangxiaoyu-HP-EliteBook-8460p.local.8008: Flags [.], ack 1, win 256, length 0

        0x0000:  4500 0028 2c2f 4000 4006 68ce c0a8 120f   E..(,/@[email protected].....

        0x0010:  c0a8 1273 f804 1f48 1f3e  083f 911e c325  ...s...H.>.?...%

        0x0020:  5010 0100 75f3 0000 0000 0000 0000       P...u.........

 

  这三个包是IP结构, 因此我们先使用IP包来分析它,然后使用TCP包结构分析。

  首先是第一个包, 由于我们是接收端, 监听的是自己计算机的8008端口, 因此第一个包是由我本地计算机由chrome浏览器发送过去的。

       可以看到第一个包的方向: DESKTOP-8TIBRLB.local.63492 > yangxiaoyu-HP-EliteBook-8460p.local.8008 (本机是台式机,叫DESKTOP-8TIBRLB 端口为 63492, 服务器是二手的惠普笔记本叫 HP-EliteBook-8460p,端口为8008)

      将包按照IP报头字段分解如下(默认16进制,0B开头为2进制):

              Version(4bits): 4

               IHL(4bits):    5

              Type of Service(8bits): 00

               Total Length(16bits): 0034

                                     Identification(16bits): 2c2e

                                     Flags(3bits):0B010

                                     Fragment Offset:00

                                     Time To Live(8bits): 40

                                     Protocol(8bits): 06

                                     Header Checksum(16bits): 68c3

                                     Source Address: c0a8 120f

                                     Destination Address: c0a8 1273

                                     Options(19bits): 无(一般 IHL>5才有Options,参阅ftp://ftp.rfc-editor.org/in-notes/std/std5.txt)

                                     Padding:无

                            Data: f804 1f48 1f3e 083e 0000 0000 8002 2000 6a74 0000 0204 05b4 0103 0308 0101 0402

                                     至此IP包分析完, Data属于TCP报头,按照TCP报头分析第一个包:

                                     Source Port: f804 (十进制为: 63492)

                                 Destation: 1f48(十进制为: 8008)

                                     Sequence Number: 1f3e 083e

                                     Acknowledge Number: 0000 0000

                                     Data Offset: 8

                                     Reserved: 0

                                     Code: 0B000010 (URG|ACK|PSH|RST|SYN|FIN)

                                     Window:2000

                                     CheckSum:6a74

                                     Urgent Pointer: 0000

                  Opations: 0204  参阅ftp://ftp.rfc-editor.org/in-notes/rfc793.txt [Page 18]

 

                                     Padding: 05b4

                                     Data: 0103 0308 0101 0402

==================================================================

                                     接下来是第二个包:

                                     Version(4bits): 4

                                     IHL(4bits):    5

                                     Type of Service(8bits): 00

                                     Total Length(16bits): 0034

                                     Identification(16bits): 0000

                                     Flags(3bits):0B010

                                     Fragment Offset:00

                                     Time To Live(8bits): 40

                                     Protocol(8bits): 06

                                     Header Checksum(16bits): 94f1

                                     Source Address: c0a8 1273  

                                     Destination Address: c0a8 120f

                                     Options(19bits): 无(一般 IHL>5才有Options,参阅ftp://ftp.rfc-editor.org/in-notes/std/std5.txt)

                                     Padding:无

                               Data: 1f48 f804 911e c324 1f3e 083f 8012 7210 a5f9 0000 0204 05b4 0101 0402 0103 0307

                                     Data属于TCP报头,按照TCP报头分析第二个包:

                                     Source Port: 1f48(十进制为: 8008)

                                  Destation: f804 (十进制为: 63492)

                                     Sequence Number: 911e c324

                                     Acknowledge Number: 1f3e 083f

                                     Data Offset: 8

                                     Reserved: 0

                                     Code: 0B010010 (URG|ACK|PSH|RST|SYN|FIN)

                                     Window: 7210

                                     CheckSum: a5f9

                                     Urgent Pointer: 0000

                  Opations: 0204  参阅ftp://ftp.rfc-editor.org/in-notes/rfc793.txt [Page 18]

                                     Padding: 05b4

                                     Data: 0101 0402 0103 0307

==================================================================

                                     接下来是第三个包:

                                     Version(4bits): 4

                                     IHL(4bits):    5

                                     Type of Service(8bits): 00

                                     Total Length(16bits): 0028

                                     Identification(16bits): 2c2f

                                     Flags(3bits):0B010

                                     Fragment Offset:00

                                     Time To Live(8bits): 40

                                     Protocol(8bits): 06

                                     Header Checksum(16bits): 68ce

                                     Source Address: c0a8 120f  

                                     Destination Address: c0a8 1273

                                     Options(19bits): 无(一般 IHL>5才有Options,参阅ftp://ftp.rfc-editor.org/in-notes/std/std5.txt)

                                     Padding:无

                               Data: f804 1f48 1f3e  083f 911e c325 5010 0100 75f3 0000 0000 0000 0000

                                     按照TCP报头分析第三个包:

                                     Source Port: f804 (十进制为: 63492)

                                     Destation: 1f48(十进制为: 8008)

                                     Sequence Number: 1f3e  083f

                                     Acknowledge Number: 911e c325

                                     Data Offset: 5

                                     Reserved: 0

                                     Code: 0B010000 (URG|ACK|PSH|RST|SYN|FIN)

                                     Window: 0100

                                     CheckSum: 75f3

                                     Urgent Pointer: 0000

                Opations: 0000参阅ftp://ftp.rfc-editor.org/in-notes/rfc793.txt [Page 18]

                                     Padding: 0000

                                     Data: 0000

==================================================================

                             我们将这三个包中的关键数据摘出来:

                             第一次:

                              由DESKTOP-8TIBRLB.local.63492 > yangxiaoyu-HP-EliteBook-8460p.local.8008

                             Sequence Number: 1f3e 083e

                             Acknowledge Number: 0000 0000

                             Code: 0B000010 (URG|ACK|PSH|RST|SYN|FIN)

                             

                             第二次:

                              由yangxiaoyu-HP-EliteBook-8460p.local.8008 > DESKTOP-8TIBRLB.local.63492

                             Sequence Number: 911e c324

                             Acknowledge Number: 1f3e 083f

                             Code: 0B010010 (URG|ACK|PSH|RST|SYN|FIN)

                             

                             第三次:

                              由yangxiaoyu-HP-EliteBook-8460p.local.8008 > DESKTOP-8TIBRLB.local.63492

                             Sequence Number: 1f3e  083f

                             Acknowledge Number: 911e c325

                             Code: 0B000010 (URG|ACK|PSH|RST|SYN|FIN)

 

        通过上面三个包, 我们可以很直观的感受到, 三次握手的过程:

  1.     前置条件:

    a) 有一个client 端和一个server端

    b) Client端使用TCP上层的传输层协议进行通信

    c) Server端监听端口

  2.     首先, client 端向sever端发送TCP报, 指定随机的Sequence Number,和Acknowledge Number = 0,并且指定code中的SYN所占的bit位为1.

  3.     然后, server 通过监听端口, 得到了client发送过来的TCP包, 发现其code中的SYN=1,且其他位为0,得知这个包的目的是请求建立可靠的连接,server端就会拿到包中的Sequence Number,将这个number + 1,得到自己的Acknowledge Number, 然后随机生成自己的Sequence Number,再将自己的code中的SYN和ACK所占的bit位都置为1. 组合成包,发送回去。  

  4.     Client端监听自己的端口, 得到了server 端发过来的包, 发现这个包中的Acknowledge Number =自己发过去的Sequence Number + 1, 于是断定server端已经同意建立连接,于是将自己的上个包的Sequence Number + 1 得到当前包中的Sequence Number, 将server发送过来的包中的Sequence Number + 1得到Acknowledge Number。指定code中的ACK所占的bit位为1, 发送回去。

  5.     图解:

   

f)  Q&A

  1)  如何记忆?

  首先需要理解 Sequence Number 代表的是client端包的序号, 因此client端发送的第二个包的Sequence Number比第一个包多1.

  然后需要记住 Acknowledge Number = 接受到的TCP包的Sequence Number +1

  最后需要记住, 只有一个SYN=1, 代表请求连接, 只有一个ACK=1,代表连接已经建立。

  2)  如果最后一个包ACK丢失了会出现什么情况?

  Server端在发出SYN/ACK后, 会等待client端发送ACK报文, 如果在一定时间内没有收到, 则重新发送SYN/ACK, 超过了一定的次数, 就会自动关闭这个连接。你想的没错, 如果client端故意不回复这个ACK, 就会在server端占用资源,这就是基于TCP的DDOS攻击。

  3)  为什么建立连接是3次握手而不是2次或者4次握手?

  我在一本计算机教材上看到这么一个例子,非常有趣,如下:

  红军给蓝军发送电文A,决定次日凌晨6点向白军发起攻击,请求蓝军协同作战。

  蓝军收到报文A, 但是又需要让红军知道自己收到了报文, 因此回复报文B给红军。

  红军收到了蓝军回复的报文B, 于是又发送了一封报文C给蓝军。

  蓝军为了让红军知道自己收到了报文C,又发一封报文D给红军。

  红军为了让蓝军知道自己收到了报文D,又发一封报文E给蓝军。

  。

  。

  。

  这个例子看起来非常愚蠢,但是在我看来,它体现了人们对100%可靠连接的迫切渴望,那么应该如何做,才能使得连接的可靠性接近或者等于100%呢?

  答案如下:

  (1)红军给蓝军发送电文,决定次日凌晨6点向白军发起攻击,请求蓝军协同作战,并等待蓝军的应答,如果在规定时间内没有收到应答,则重发请求;
  (2)蓝军如果收到红军的作战报文后,则回送一个响应报文,表明已知道次日凌晨6点向白军发起攻击且愿意协同作战,并等待红军1的确认,如果在规定时间内没有收到确认报文,则重发响应报文;
  (3)红军收到蓝军的响应报文,再向蓝军发送一个确认报文,并表明已知道蓝军将协同作战。

 

  请注意, 这份答案和上面的区别在于第1和第2条中有如果在规定时间内没有收到确认报文,则重发报文.

  完成!

猜你喜欢

转载自www.cnblogs.com/syyxy/p/9500280.html