TCP协议连接建立时3次握手的过程4次结束连接

[转载]TCP协议连接建立时3次握手的过程4次结束连接



分析tcp报文

http://hi.baidu.com/nostop/blog/item/ffc0d358d4fa5a97800a18f9.html

tcpdump -i eth0 port 80 and host 10.6.48.137 -X

0x0000: 4500 0030 d9cb 4000 7b06 aa98 0a063089  E..0..@.{.....0.
0x0010:  0a0b 36ca 0864 0050 99fa a8a9 0000 0000 ..6..d.P........
0x0020:  7002 ffff bcb3 0000 0204 0564 01010402  p..........d....

4 Version 4
4 IHL 5
8 Type of Service 00
16 Total Lengt 0030
16 Identification d9cb
3 Flags 010b
13 Fragment Offset 00000
8 Time to Live 7b
8 Protocol 06
16 Header Checksum aa98
32 Source Address 0a06 3089
32 Destination Address 0a0b 36ca


16 Source port 0864
16 Destination port 0050
32 Sequence number 99fa a8a9
32 Acknowledgment number 00000000
4 Data offset 7
4 Reserved 0
1 CWR 0
1 ECE 0
1 URG 0
1 ACK 0
1 PSH 0
1 RST 0
1 SYN 1
1 FIN 0
16 Window Size ffff
16 Checksum bcb3
16 Urgent pointer 0000

三次握手
14:00:07.759656 IP (tos 0x0, ttl 123, id 55755, offset 0, flags[DF], proto 6, length: 48) 10.6.48.137.2148 >cas.us.changyou.com.http: S [tcp sum ok] 2583341225:2583341225(0)win 65535 <mss1380,nop,nop,sackOK>
              0x0000:  4500 0030 d9cb 4000 7b06 aa98 0a063089  E..0..@.{.....0.
              0x0010:  0a0b 36ca 0864 0050 99fa a8a9 00000000  ..6..d.P........
              0x0020:  7002 ffff bcb3 0000 0204 0564 01010402  p..........d....
14:00:08.077763 IP (tos 0x0, ttl  64, id 0, offset0, flags [DF], proto 6, length: 44) cas.us.changyou.com.http> 10.6.48.137.2148: S [tcp sum ok]1877247558:1877247558(0) ack 2583341226 win 5840<mss 1460>
              0x0000:  4500 002c 0000 4000 4006 bf68 0a0b36ca  E..,..@.@..h..6.
              0x0010:  0a06 3089 0050 0864 6fe4 8646 99faa8aa  ..0..P.do..F....
              0x0020:  6012 16d0 c45e 0000 020405b4                      `....^......
14:00:07.761795 IP (tos 0x0, ttl 123, id 55756, offset 0, flags[DF], proto 6, length: 40) 10.6.48.137.2148 >cas.us.changyou.com.http: . [tcp sum ok] ack 1 win 65535
              0x0000:  4500 0028 d9cc 4000 7b06 aa9f 0a063089  E..(..@.{.....0.
              0x0010:  0a0b 36ca 0864 0050 99fa a8aa 6fe48647  ..6..d.P....o..G
              0x0020:  5010 ffff f2eb 0000 0000 00000000            P.............

1) client to server
syn 1
ack 0
Sequence number 99fa a8a9
Acknowledgment number 0000 0000

2) server to client
syn 1
ack 1
Sequence number 6fe4 8646
Acknowledgment number 99fa a8aa

3)client to server
syn 0
ack 1
Sequence number 99fa a8aa
Acknowledgment number 6fe4 8647



四次挥手
14:05:09.975592 IP (tos 0x0, ttl  64, id 56648,offset 0, flags [DF], proto 6, length: 40) cas.us.changyou.com.http> 10.6.48.137.2148: F [tcp sum ok] 1:1(0) ack 1 win5840
              0x0000:  4500 0028 dd48 4000 4006 e223 0a0b36ca  E..(.H@.@..#..6.
              0x0010:  0a06 3089 0050 0864 6fe4 8647 99faa8aa  ..0..P.do..G....
              0x0020:  5011 16d0 dc1a0000                                          P.......
14:05:09.976681 IP (tos 0x0, ttl 123, id 57732, offset 0, flags[DF], proto 6, length: 40) 10.6.48.137.2148 >cas.us.changyou.com.http: . [tcp sum ok] ack 2 win 65535
              0x0000:  4500 0028 e184 4000 7b06 a2e7 0a063089  E..(..@.{.....0.
              0x0010:  0a0b 36ca 0864 0050 99fa a8aa 6fe48648  ..6..d.P....o..H
              0x0020:  5010 ffff f2ea 0000 0000 00000000            P.............
14:05:09.977386 IP (tos 0x0, ttl 123, id 57733, offset 0, flags[DF], proto 6, length: 40) 10.6.48.137.2148 >cas.us.changyou.com.http: F [tcp sum ok] 1:1(0) ack 2 win65535
              0x0000:  4500 0028 e185 4000 7b06 a2e6 0a063089  E..(..@.{.....0.
              0x0010:  0a0b 36ca 0864 0050 99fa a8aa 6fe48648  ..6..d.P....o..H
              0x0020:  5011 ffff f2e9 0000 0000 00000000            P.............
14:05:09.977431 IP (tos 0x0, ttl  64, id 0, offset0, flags [DF], proto 6, length: 40) cas.us.changyou.com.http> 10.6.48.137.2148: . [tcp sum ok] ack 2 win5840
              0x0000:  4500 0028 0000 4000 4006 bf6c 0a0b36ca  E..(..@.@..l..6.
              0x0010:  0a06 3089 0050 0864 6fe4 8648 99faa8ab  ..0..P.do..H....
              0x0020:  5010 16d0 dc190000                                          P.......

1) server to client
fin 1
ack 1
Sequence number 6fe4 8647
Acknowledgment number 99fa a8aa

2) client to server
fin 0
ack 1
Sequence number 99fa a8aa
Acknowledgment number 6fe4 8648

3) client to server
fin 1
ack 1
Sequence number 99fa a8aa
Acknowledgment number 6fe4 8648

4) server to client
fin 0
ack 1
Sequence number 6fe4 8648
Acknowledgment number 99fa a8ab


打开一个终端,输入以下命令。

sudo tcpdumptcp –Vx –i eth0

打开另一终端,输入

telnetwww.baidu.com80

在命令提示符下输入

GET/HTTP/1.1

      通过以上操作,抓了IP数据包,首先来看抓到的第一个数据包。

      

       06:36:44.571131IP (tos 0x10, ttl 64, id 61341, offset 0, flags [DF], proto TCP(6), length 60)

    ubuntu.45186> 119.75.218.70.www: Flags [S], cksum 0xaa58(correct), seq 455838797, win

5840,options [mss 1460,sackOK,TS val 156624 ecr 0,nop,wscale 6], length0

       0x0000:  4510003c ef9d 4000 4006 8053 c0a8 b880  E..<..@.@..S....

       0x0010:  774bda46 b082 0050 1b2b 8c4d 0000 0000  wK.F...P.+.M....

       0x0020:  a00216d0 aa58 0000 0204 05b4 0402 080a  .....X..........

       0x0030:  000263d0 0000 0000 0103 0306            ..c.........

 

      以下是IP数据报的头部定义。我们参照抓取到的第一个数据包来解读都有哪些信息可以读取出来。

0                   1                   2                   3   

    01 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 01

   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   |Version|  IHL  |Typeof Service|          TotalLength         |

   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   |         Identification        |Flags|      FragmentOffset    |

   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   |  Timeto Live |    Protocol   |         HeaderChecksum       |

   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   |                       SourceAddress                          |

   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   |                    DestinationAddress                        |

   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   |                    Options                    |    Padding    |

   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

 

Version IP协议的版本号,占4bit.数据包中的第一位为4,即表示为该数据包为IPv4

IHL(Internet HeaderLength) 包头长度的字节数包含多少个32位。4bit位。5表示头部共有5*4=20Byte

由于有4位,即12,包头长度最大为60字节

Type ofService(服务类型,TOS)共由8bit组成其中每个bit的组合分别代表不同的意思。4bit中只能置其中1bit
如果所有
4bit均为0,那么就意味着是一般服务。

TotalLength指定IP包的总长,通常以byte做单位来表示该封包的总长度此数值包括标头和数据的总和。它以字节为单位,
16位。003c换算为十进制即为60,表示总长度为60Byte

Identification每一个IP封包都有一个16位的唯一识别码。当程序产生的数据要通过网络传送时都会被拆散成封包形式发送,
当封包要进行重组的时候这个
ID就是依据了。占16位。ef9d即表示为该ip包的ID61341

Flags表示片标志,占3BIT。各位含义分别为:第一个“0被保留,第二个DF,0为分片标志位,“1表示不能分段,
0表示分段。第三个MF,0为是否最后一片标志位,0表示最后一片,1表示还有更多的片。该标志位置为010
从数据包中分析,即表示不可分段,且为最后一片。

FragmentOffset分段便移,在重组的时候就能够对号入座。占13位。封包并没有被分段,则FO值为“0”

Time toLive生存时间字段设置了数据报可以经过的最多路由器数,表示数据包在网络上生存多久。占8位。该包为0x40,即64.

Protocol 表示传输层的协议类型。在RFC790中有定义,6表示传输层是TCP协议。 

HeaderChecksum头校验和。16bit。该包为8053

SourceAddress IP源地址。c0a8b880 改写为十进制即为192.168.184.128

DestinationAddress IP目的地址。774bda46即为119.75.218.70

 http://hi.baidu.com/nostop/blog/item/6c6640a78176fe83d14358f9.html


使用tcpdump抓取IP数据包+TCP连接过程分析(二)

TCP头部定义为下

TCPHeader

Bitoffset

0

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

26

27

28

29

30

31

0

Sourceport

Destinationport

32

Sequencenumber

64

Acknowledgmentnumber

96

Dataoffset

Reserved

C
W
R

E
C
E

U
R
G

A
C
K

P
S
H

R
S
T

S
Y
N

F
I
N

WindowSize

128

Checksum

Urgentpointer

160
...

Options (ifData Offset > 5)
...

padding

 

       0x0000:  4510003c ef9d 4000 4006 8053 c0a8 b880  E..<..@.@..S....

       0x0010:  774bda46 b082 00501b2b 8c4d 0000 0000  wK.F...P.+.M....

       0x0020:  a002 16d0aa58 0000 0204 05b4 0402 080a  .....X..........

       0x0030:  000263d0 0000 0000 0103 0306            ..c.........

 

 

源端口号b082即端口为45186

目的端口号0050即端口为80

顺序号(SequenceNumber)简写为SEQ1b2b8c4dSEQ=455838797

确认号(AcknowledgmentNumber)简写为ACKNUM00000000即这个包的确认号为0

数据偏移(DataOffset)表示数据偏移的大小。4bita10byte,大于5byte

保留位(Reserved)此处不用。4bit

Flag8bit

CWR保留为0

ECE保留为0

 URG,紧急数据标志,为1表示有紧急数据,应立即进行传递。 

 ACK,确认标志位,为1表示此数据包为应答数据包 

 PSHPUSH标志位,为1表示此数据包应立即进行传递。 

 RST:复位标志位。如果收到不属于本机的数据包,则返回一个RST 

 SYN:连接请求标志位。为1表示为发起连接的请求数据包。 

 FIN:结束连接请求标志位。为1表示是结束连接的请求数据包。

窗口大小(WindowsSize16d05840

校验和(Checksumaa58

紧急指针(Urgentpointer0000


http://hi.baidu.com/nostop/blog/item/ce765b826cf3e6b40cf4d2f9.html
使用tcpdump抓取IP数据包+TCP连接过程分析(三)

下面分析3次握手过程

06:36:44.571131IP (tos 0x10, ttl 64, id 61341, offset 0, flags [DF], proto TCP(6), length 60)

    ubuntu.45186> 119.75.218.70.www: Flags [S], cksum 0xaa58(correct), seq 455838797, win 5840, options [mss 1460,sackOK,TS val156624 ecr 0,nop,wscale 6], length 0

         0x0000:  4510003c ef9d 4000 4006 8053 c0a8 b880  E..<..@.@..S....

         0x0010:  774bda46 b082 0050 1b2b 8c4d 0000 0000  wK.F...P.+.M....

         0x0020:  a002 16d0aa58 0000 020405b4 0402 080a  .....X..........

         0x0030:  000263d0 0000 0000 0103 0306            ..c.........

这个报文是刚才已经分析过的。客户端向服务器发送TELNET请求,服务器地址是119.75.218.70,端口为80SYN1ACK0
即为发起连接请求数据包。
Seq455838797,ACKNUM0

 

06:36:44.631571IP (tos 0x0, ttl 128, id 65273, offset 0, flags [none], proto TCP(6), length 44)

119.75.218.70.www> ubuntu.45186: Flags [S.], cksum 0xa942 (correct),seq 1634168692, ack 455838798, win 64240, options [mss 1460],
length 0

         0x0000:  4500002c fef9 0000 8006 7117 774b da46  E..,......q.wK.F

         0x0010:  c0a8b880 0050 b082 6167 6f74 1b2b 8c4e  .....P..agot.+.N

         0x0020:  6012 faf0a942 0000 0204 05b40000       `....B........

这个报文为服务器向客户端返回的请求。可见SYN1.ACK1。即也为应答数据包,发起连接请求。ACKNUM455838798
SEQ1634168692

 

06:36:44.631706IP (tos 0x10, ttl 64, id 61342, offset 0, flags [DF], proto TCP(6), length 40)

    ubuntu.45186> 119.75.218.70.www: Flags [.], cksum 0xa520(correct), ack 1, win 5840, length 0

         0x0000:  45100028 ef9e 4000 4006 8066 c0a8 b880  E..(..@.@..f....

         0x0010:  774bda46 b082 0050 1b2b 8c4e 6167 6f75  wK.F...P.+.Nagou

         0x0020:  5010 16d0a520 0000                      P.......

客户端再次向服务器发送确认。SYN0ACK1,即为应答数据包,SEQ1b2b,即2859ACKNUM1b2b8c4e
即与服务器端发送来的
SEQ一致,为1634168692SEQ61676f75,即为服务器端ACKNUM+1.

至此,TCP连接已经建立了。

 

06:37:13.738326IP (tos 0x10, ttl 64, id 61343, offset 0, flags [DF], proto TCP(6), length 55)

    ubuntu.45186> 119.75.218.70.www: Flags [P.], cksum 0xc99c(correct), seq 1:16, ack 1, win 5840, length 15

         0x0000:  45100037 ef9f 4000 4006 8056 c0a8 b880  E..7..@.@..V....

         0x0010:  774bda46 b082 0050 1b2b 8c4e 6167 6f75  wK.F...P.+.Nagou

         0x0020:  501816d0 c99c 0000 4745 5420 2f48 5454  P.......GET./HTT

         0x0030:  502f312e 310d 0a                        P/1.1..

此时,客户端想服务器端发送GET/HTTP./1.1请求。继续沿用之前的ACKNUM1b2b8c4eSEQ61676f75

 

06:37:13.739745IP (tos 0x0, ttl 128, id 65274, offset 0, flags [none], proto TCP(6), length 40)

    119.75.218.70.www> ubuntu.45186: Flags [.], cksum 0xc0f0 (correct),ack 16, win 64240, length 0

         0x0000:  45000028 fefa 0000 8006 711a 774b da46  E..(......q.wK.F

         0x0010:  c0a8b880 0050 b082 6167 6f75 1b2b 8c5d  .....P..agou.+.]

         0x0020:  5010faf0 c0f0 0000 0000 0000 0000       P.............

服务器返回请求。SEQ61676f75ACK1b2b8c5d

 

06:37:22.154444IP (tos 0x10, ttl 64, id 61344, offset 0, flags [DF], proto TCP(6), length 42)

    ubuntu.45186> 119.75.218.70.www: Flags [P.], cksum 0x97fd(correct), seq 16:18, ack 1, win 5840, length 2

         0x0000:  4510002a efa0 4000 4006 8062 c0a8 b880  E..*..@.@..b....

         0x0010:  774bda46 b082 0050 1b2b 8c5d 6167 6f75  wK.F...P.+.]agou

         0x0020:  501816d0 97fd 0000 0d0a                 P.........

客户端确认返回请求。SEQ1b2b8c5dACK61676f75

 

最后看断开连接。

由于telnetbaidu.com经常被异常断开。所以这里用telnetwww.google.com80分析断开连接过程。

09:27:56.524576IP (tos 0x10, ttl 64, id 57544, offset 0, flags [DF], proto TCP(6), length 40)

    ubuntu.53355> hx-in-f99.1e100.net.www: Flags [F.], cksum 0x8d2f(correct), seq 1, ack 1, win 5840, length 0

         0x0000:  45100028 e0c8 4000 4006 4eed c0a8 b881  E..(..@.@.N.....

         0x0010:  4a7d4763 d06b 0050 fb12 9353 289f 7908  J}Gc.k.P...S(.y.

         0x0020:  501116d0 8d2f 0000                      P..../..

客户端向服务器发送请求,要求断开连接。FIN1ACK1SEQ:fb12 9353, ACKNUM:289f 7908.

 

09:27:56.525632IP (tos 0x0, ttl 128, id 545, offset 0, flags [none], proto TCP(6), length 40)

    hx-in-f99.1e100.net.www> ubuntu.53355: Flags [.], cksum 0xa90f (correct),ack 2, win 64239, length 0

         0x0000:  45000028 0221 0000 8006 2da5 4a7d 4763  E..(.!....-.J}Gc

         0x0010:  c0a8b881 0050 d06b 289f 7908 fb12 9354  .....P.k(.y....T

         0x0020:  5010faef a90f 0000 0000 0000 0000       P.............

服务器向客户机发送确认断开,ACK:1,SEQ:289f 7908,与客户端ACKNUM一致。ACKNUM:fb12 9354,为客户端ACKNUM+1.

 

09:27:56.592668IP (tos 0x0, ttl 128, id 546, offset 0, flags [none], proto TCP(6), length 40)

    hx-in-f99.1e100.net.www> ubuntu.53355: Flags [FP.], cksum 0xa906 (correct),seq 1, ack 2, win 64239, length 0

         0x0000:  45000028 0222 0000 8006 2da4 4a7d 4763  E..(."....-.J}Gc

         0x0010:  c0a8b881 0050 d06b 289f 7908 fb12 9354  .....P.k(.y....T

         0x0020:  5019faef a906 0000 0000 0000 0000       P.............

服务器再次向客户机发送断开,FIN1URG1ACK1.SEQ:289f 7908,与客户端ACKNUM一致,ACKNUM:  fb129354
为客户端
ACKNUM+1.

 

09:27:56.593407IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6),length 40)

    ubuntu.53355> hx-in-f99.1e100.net.www: Flags [.], cksum 0x8d2e(correct), ack 2, win 5840, length 0

         0x0000:  45000028 0000 4000 4006 2fc6 c0a8 b881  E..(..@.@./.....

         0x0010:  4a7d4763 d06b 0050 fb12 9354 289f 7909  J}Gc.k.P...T(.y.

         0x0020:  501016d0 8d2e 0000                      P.......

客户端向服务器端发送确认,ACK:1SEQ:fb12 9354 ,与服务器ACKNUM一致,ACKNUM.289f 7909为服务器ACKNUM+1.

 

至此TCP连接,发送命令与数据,断开连接三个过程分析完毕。,




11种状态 :

http://hi.baidu.com/smilehaha/blog/item/b4e16ca81bdeafa6cb130cfe.html

http://ronbin.com/81.htm


摘自:http://blog.csdn.net/lmsnju/article/details/4916229

在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接,如图1所示。

(1)第一次握手:建立连接时,客户端A发送SYN包(SYN=j)到服务器B,并进入SYN_SEND状态,等待服务器B确认。

(2)第二次握手:服务器B收到SYN包,必须确认客户A的SYN(ACK=j+1),同时自己也发送一个SYN包(SYN=k),即SYN+ACK包,此时服务器B进入SYN_RECV状态。

(3)第三次握手:客户端A收到服务器B的SYN+ACK包,向服务器B发送确认包ACK(ACK=k+1),此包发送完毕,客户端A和服务器B进入ESTABLISHED状态,完成三次握手。

完成三次握手,客户端与服务器开始传送数据。

                              图1 TCP三次握手建立连接

由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。

(1)客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送(报文段4)。

(2)服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1(报文段5)。和SYN一样,一个FIN将占用一个序号。

(3)服务器B关闭与客户端A的连接,发送一个FIN给客户端A(报文段6)。

(4)客户端A发回ACK报文确认,并将确认序号设置为收到序号加1(报文段7)。

TCP采用四次挥手关闭连接如图2所示。

                              图2  TCP四次挥手关闭连接

1.为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?

这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的建连请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。

2.为什么TIME_WAIT状态还需要等2MSL后才能返回到CLOSED状态?

这是因为虽然双方都同意关闭连接了,而且握手的4个报文也都协调和发送完毕,按理可以直接回到CLOSED状态(就好比从SYN_SEND状态到ESTABLISH状态那样);但是因为我们必须要假想网络是不可靠的,你无法保证你最后发送的ACK报文会一定被对方收到,因此对方处于LAST_ACK状态下的SOCKET可能会因为超时未收到ACK报文,而重发FIN报文,所以这个TIME_WAIT状态的作用就是用来重发可能丢失的ACK报文。


摘自:http://blog.csdn.net/eroswang/article/details/3080217

TCP协议连接建立时3次握手的过程。

简述TCP协议连接建立时3次握手的过程。

根据TCP头部,说明下列3个包在连接建立过程中的次序.

0020        0050 83 aa 46 49 3e dd 33 96 37 a3 a012  ...P..FI>.3.7...

0030   16a0 c4 c0 00 00 02 04 05 b4 04 02 08 0a d79b  ................

0040   62b7 00 56 4a 2a 01 03 0302                    b..VJ*....   1

0020        83aa 00 50 33 96 37 a2 00 00 00 00 a002  .....P3.7.......

0030   16d0 84 1d 00 00 02 04 05 b4 04 02 08 0a 0056  ...............V

0040   4a2a 00 00 00 00 01 03 0300                    J*........    2

0020        83aa 00 50 33 96 37 a3 46 49 3e de 8010  .....P3.7.FI>...

0030   16d0 f3 4b 00 00 01 01 08 0a 00 56 4a 36 d79b  ...K.......VJ6..

0040   62b7                                            b.   3

解:

TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。

1)是第二次握手,flags位上为12,二进制是00010010,即表示有synack.

2)是第一次握手,flags位上为02,二进制是00000010,即表示有syn没有ack

3)是第三次握手,flags位上为10,二进制是00010000,即表示有ack没有syn

该连接访问的是80端口,是为HTTPHyperTextTransportProtocol,超文本传输协议)开放的,

第一次握手:建立连接时,客户端发送syn(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;

第二次握手:服务器收到syn包,必须确认客户的SYNack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;


第三次握手:客户端收到服务器的SYNACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。


完成三次握手,客户端与服务器开始传送数据。

tcp-断开连接:

 

主要部分,四次握手:

断开连接其实从我的角度看不区分客户端和服务器端,任何一方都可以调用close(orclosesocket)之类
的函数开始主动终止一个连接。这里先暂时说正常情况。当调用close函数断开一个连接时,主动断开的
一方发送FIN(finish报文给对方。有了之前的经验,我想你应该明白我说的FIN报文时什么东西。也就是
一个设置了FIN标志位的报文段。FIN报文也可能附加用户数据,如果这一方还有数据要发送时,将数据附
加到这个FIN报文时完全正常的。之后你会看到,这种附加报文还会有很多,例如ACK报文。我们所要把握
的原则是,TCP肯定会力所能及地达到最大效率,所以你能够想到的优化方法,我想TCP都会想到。

当被动关闭的一方收到FIN报文时,它会发送ACK确认报文(对于ACK这个东西你应该很熟悉了)。这里有个
东西要注意,因为TCP是双工的,也就是说,你可以想象一对TCP连接上有两条数据通路。当发送FIN报文
时,意思是说,发送FIN的一端就不能发送数据,也就是关闭了其中一条数据通路。被动关闭的一端发送
了ACK后,应用层通常就会检测到这个连接即将断开,然后被动断开的应用层调用close关闭连接。

我可以告诉你,一旦当你调用close(orclosesocket),这一端就会发送FIN报文。也就是说,现在被动
关闭的一端也发送FIN给主动关闭端。有时候,被动关闭端会将ACK和FIN两个报文合在一起发送。主动
关闭端收到FIN后也发送ACK,然后整个连接关闭(事实上还没完全关闭,只是关闭需要交换的报文发送
完毕),四次握手完成。如你所见,因为被动关闭端可能会将ACK和FIN合到一起发送,所以这也算不上
严格的四次握手---四个报文段。

在前面的文章中,我一直没提TCP的状态转换。在这里我还是在犹豫是不是该将那张四处通用的图拿出来,
不过,这里我只给出断开连接时的状态转换图,摘自<The TCP/IPGuide>:

tcpclose

给出一个正常关闭时的windump信息:

[转载]TCP协议连接建立时3次握手的过程4次结束连接14:00:38.819856 IP cd-zhangmin.1748 > 220.181.37.55.80: F 1:1(0)ack 1 win 65535
[转载]TCP协议连接建立时3次握手的过程4次结束连接
14:00:38.863989 IP 220.181.37.55.80 > cd-zhangmin.1748: F 1:1(0)ack 2 win 2920
[转载]TCP协议连接建立时3次握手的过程4次结束连接
14:00:38.864412 IP cd-zhangmin.1748 > 220.181.37.55.80: . ack 2 win 65535

补充细节:

关于以上的四次握手,我补充下细节:
1. 默认情况下(不改变socket选项),当你调用close( orclosesocket,以下说close不再重复)时,如果
发送缓冲中还有数据,TCP会继续把数据发送完。


2.发送了FIN只是表示这端不能继续发送数据(应用层不能再调用send发送),但是还可以接收数据。


3. 应用层如何知道对端关闭?通常,在最简单的阻塞模型中,当你调用recv时,如果返回0,则表示对端
关闭。在这个时候通常的做法就是也调用close,那么TCP层就发送FIN,继续完成四次握手。如果你不调用
close,那么对端就会处于FIN_WAIT_2状态,而本端则会处于CLOSE_WAIT状态。这个可以写代码试试。


4. 在很多时候,TCP连接的断开都会由TCP层自动进行,例如你CTRL+C终止你的程序,TCP连接依然会正常关
闭,你可以写代码试试。

 

 

特别的TIME_WAIT状态:

从以上TCP连接关闭的状态转换图可以看出,主动关闭的一方在发送完对对方FIN报文的确认(ACK)报文后,
会进入TIME_WAIT状态。TIME_WAIT状态也称为2MSL状态。

什么是2MSL?MSL即Maximum SegmentLifetime,也就是报文最大生存时间,引用<TCP/IP详解>中的话:“
它(MSL)是任何报文段被丢弃前在网络内的最长时间。”那么,2MSL也就是这个时间的2倍。其实我觉得没
必要把这个MSL的确切含义搞明白,你所需要明白的是,当TCP连接完成四个报文段的交换时,主动关闭的
一方将继续等待一定时间(2-4分钟),即使两端的应用程序结束。你可以写代码试试,然后用netstat查看下。

为什么需要2MSL?根据<TCP/IP详解>和<TheTCP/IP Guide>中的说法,有两个原因:
其一,保证发送的ACK会成功发送到对方,如何保证?我觉得可能是通过超时计时器发送。这个就很难用
代码演示了。
其二,报文可能会被混淆,意思是说,其他时候的连接可能会被当作本次的连接。直接引用<The TCP/IPGuide>
的说法:The second is to provide a “buffering period” between the endof this connection
and any subsequent ones. If not for this period, it is possiblethat packets from different
connections could be mixed, creating confusion.

TIME_WAIT状态所带来的影响:

当某个连接的一端处于TIME_WAIT状态时,该连接将不能再被使用。事实上,对于我们比较有现实意义的
是,这个端口将不能再被使用。某个端口处于TIME_WAIT状态(其实应该是这个连接)时,这意味着这个TCP
连接并没有断开(完全断开),那么,如果你bind这个端口,就会失败。

对于服务器而言,如果服务器突然crash掉了,那么它将无法再2MSL内重新启动,因为bind会失败。解决这
个问题的一个方法就是设置socket的SO_REUSEADDR选项。这个选项意味着你可以重用一个地址。

对于TIME_WAIT的插曲:

当建立一个TCP连接时,服务器端会继续用原有端口监听,同时用这个端口与客户端通信。而客户端默认情况
下会使用一个随机端口与服务器端的监听端口通信。有时候,为了服务器端的安全性,我们需要对客户端进行
验证,即限定某个IP某个特定端口的客户端。客户端可以使用bind来使用特定的端口。

对于服务器端,当设置了SO_REUSEADDR选项时,它可以在2MSL内启动并listen成功。但是对于客户端,当使
用bind并设置SO_REUSEADDR时,如果在2MSL内启动,虽然bind会成功,但是在windows平台上connect会失败。
而在linux上则不存在这个问题。(我的实验平台:winxp, ubuntu7.10)

要解决windows平台的这个问题,可以设置SO_LINGER选项。SO_LINGER选项决定调用close时,TCP的行为。
SO_LINGER涉及到linger结构体,如果设置结构体中l_onoff为非0,l_linger为0,那么调用close时TCP连接
会立刻断开,TCP不会将发送缓冲中未发送的数据发送,而是立即发送一个RST报文给对方,这个时候TCP连
接就不会进入TIME_WAIT状态。

如你所见,这样做虽然解决了问题,但是并不安全。通过以上方式设置SO_LINGER状态,等同于设置SO_DONTLINGER
状态。

断开连接时的意外:
这个算不上断开连接时的意外,当TCP连接发生一些物理上的意外情况时,例如网线断开,linux上的TCP实现
会依然认为该连接有效,而windows则会在一定时间后返回错误信息。

这似乎可以通过设置SO_KEEPALIVE选项来解决,不过不知道这个选项是否对于所有平台都有效。


[转载]TCP协议连接建立时3次握手的过程4次结束连接


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值