赞
踩
1、TCP建立连接需要3次握手
首先,client端会发出一个SYN,server收到之后,会回复ACK,并同时发出一个SYN,client收到后连接就可以建立。三次握手保证了双发通讯正常。
这就和我们打电话一样:
张三:在吗?(向李四发出信息,等待李四响应)
李四:在。 (李四收到信息后,回复张三;到这里只能说明张三的消息,李四可以收到。所以要保证通讯畅通,李四需要向张三发出信息,等待张三回复。)
张三:收到。 (这里张三回复收到,则意味着李四发出的信息,张三也可以收到。 这样才建立一个可靠的连接)
2、TCP连接断开需要四次挥手
图中的client、service只是为了描述一个连接关闭流程,实际上不管客户端还是服务端都可以主动关闭连接。
为什么需要四次挥手呢?
TCP是全双工通讯,当收到对方发来的FIN包,只意味着对方可以关闭连接了,自己可能还有数据要发送。所以FIN需要单独在发一次。
3、TCP状态转移图
Closed: 是初始状态
Listen:表示服务器的某个socket处于监听状态,可以接受连接
SYN_rcvd:表示收到了SYN报文,这是服务器的一个中间态、很短暂。
SYN_send:客户端发送SYN报文后,会变成这个状态,与SYN_rcvd对应。
Established:表明连接已经建立,这可以说是一个稳定态,使用netstat 可以观察到双方建立的连接。
Close_wait:正常来说,这应该也是一个中间态,它代表着四次挥手中收到对方发来的FIN,回复了ack,在向对方发送FIN之前,就是这个状态。 (很多时候我们会发现程序出问题时出现很多close_wait,这个状态出现就是由于在收到对方关闭连接后,自身未发出FIN包导致。大量的close_wait状态会导致HTTP请求无法响应,你的程序会宕掉,你需要检查一下你的代码了)
LAST_ack:这个状态是被动关闭的一方发送FIN后,等待四次握手中最后一个Ack(也就是主动关闭方发来的ack)之前的状态。
FIN_wait_1:这也是个中间态,基本看不到。当主动关闭方向对方发送FIN报文后,主动方便是FIN_wait_1状态。
FIN_wait_2:接着上面FIN_wait1说的,在主动关闭连接的一方发送FIN报文后,自身成为FIN_wait1,当收到对方的ACK时,变为FIN_wait_2。
TIME_wait:接受到对方的FIN,并回复了ack。此时等待2MSL(MSL为最长报文存活时间,可在操作系统中配置),连接即可关闭。这是一个正常态,存在请求时netstat即可看到。
closing:比较特殊,可能是双发同时关闭连接时会出现的状态。图中可以看到,之后会变为Time_wait,2MSL后连接随之关闭。
4、来看一个HTTP请求的抓包
浮生若梦,忙里偷闲, 使用tcpdump抓包来看看一次HTTP请求TCP连接的建立断开。
一个正常的HTTP请求抓包
- tcpdump -i lo -n port 8080 -S
-
- #tcpdump用法自己百度一下
我们触发一次
- 15:58:19.333425 IP 127.0.0.1.49455 > 127.0.0.1.8080: Flags [S], seq 4076194383, win 43690, options [mss 65495,sackOK,TS val 1559458260 ecr 0,nop,wscale 7], length 0
- 15:58:19.333436 IP 127.0.0.1.8080 > 127.0.0.1.49455: Flags [S.], seq 2069165181, ack 4076194384, win 43690, options [mss 65495,sackOK,TS val 1559458260 ecr 1559458260,nop,wscale 7], length 0
- 15:58:19.333448 IP 127.0.0.1.49455 > 127.0.0.1.8080: Flags [.], ack 2069165182, win 342, options [nop,nop,TS val 1559458260 ecr 1559458260], length 0
- 15:58:19.333548 IP 127.0.0.1.49455 > 127.0.0.1.8080: Flags [P.], seq 4076194384:4076195143, ack 2069165182, win 342, options [nop,nop,TS val 1559458260 ecr 1559458260], length 759
- 15:58:19.333562 IP 127.0.0.1.8080 > 127.0.0.1.49455: Flags [.], ack 4076195143, win 354, options [nop,nop,TS val 1559458260 ecr 1559458260], length 0
- 15:58:19.353547 IP 127.0.0.1.8080 > 127.0.0.1.49455: Flags [P.], seq 2069165182:2069165253, ack 4076195143, win 354, options [nop,nop,TS val 1559458280 ecr 1559458260], length 71
- 15:58:19.353557 IP 127.0.0.1.49455 > 127.0.0.1.8080: Flags [.], ack 2069165253, win 342, options [nop,nop,TS val 1559458280 ecr 1559458280], length 0
- 15:58:19.353835 IP 127.0.0.1.8080 > 127.0.0.1.49455: Flags [P.], seq 2069165253:2069165340, ack 4076195143, win 354, options [nop,nop,TS val 1559458281 ecr 1559458280], length 87
- 15:58:19.353843 IP 127.0.0.1.49455 > 127.0.0.1.8080: Flags [.], ack 2069165340, win 342, options [nop,nop,TS val 1559458281 ecr 1559458281], length 0
- 15:58:19.354004 IP 127.0.0.1.49455 > 127.0.0.1.8080: Flags [F.], seq 4076195143, ack 2069165340, win 342, options [nop,nop,TS val 1559458281 ecr 1559458281], length 0
- 15:58:19.354228 IP 127.0.0.1.8080 > 127.0.0.1.49455: Flags [F.], seq 2069165340, ack 4076195144, win 354, options [nop,nop,TS val 1559458281 ecr 1559458281], length 0
- 15:58:19.354239 IP 127.0.0.1.49455 > 127.0.0.1.8080: Flags [.], ack 2069165341, win 342, options [nop,nop,TS val 1559458281 ecr 1559458281], length 0
TCP Flag包含8个比特位,分别是:CWR,ECE,URG,ACK,PSH,RST,SYN,FIN。
SYN:在建立连接时标记,三次握手中syn就是这个.
ACK:用来告诉对方数据包已收到,返回的数据中会将顺序号+1.
PSH:(push)表示需要将收到的包交给应用层.
FIN:表示自己已经没有数据要发送了,准备关闭连接.
看一下抓包数据,前三个包,就是三次握手建立连接的过程:第一个包Flags[S] 代表客户端发送的SYN,第二个包Flags[S.]代表服务端返回的ack和向客户端发出的SYN,第三个包Flags[.]是客户端回复的ack.至此三次握手完成,连接建立。
中间的包是请求和响应,来看最后三个包.就是四次挥手来关闭连接。
Flags[F.]代表主动关闭的一方没有数据发送了,向对方发送了FIN来关闭连接。倒数第二个包Flags[F.]表示被动一方回复ack,并且发出FIN表示也要关闭连接了(这里FIN与ack一起发可以理解为TCP自身的优化机制),最后一个包F[.]主动关闭一方回复ack,连接关闭。
再来分析一下Flags[P]包中数据的含义:
15:58:19.333548 IP 127.0.0.1.49455 > 127.0.0.1.8080: Flags [P.], seq 4076194384:4076195143, ack 2069165182, win 342, options [nop,nop,TS val 1559458260 ecr 1559458260], length 759
15:58:19.333548: 这个一看就是收到包时间了
127.0.0.1.49455 :是发送方的IP和端口
127.0.0.1.8080 :是服务端的IP和端口
Flags [P.] :P代表PSH标志位,表明改包需要推送到应用层,至于这里的.可以理解为一个占位符,不考虑。
seq 4076194384:4076195143 : tcp报文的seq号, 4076194384是起始值,4076195143是结束值, 4076195143 -4076194384是发送报文长度。
ack 2069165182 :tcp报文的ack号, ack 2069165182 表明标号2069165181报文已收到。下一个接收的seq号会从2069165182 开始。
win 342 :表示tcp报文发送方作为接收方还可以接受的字节数,大于这个数,可能就处理不了了。
options [nop,nop,TS val 1559458260 ecr 1559458260]:这里nop是 no operation,可以不考虑;TS val 1559458260是报文的时间戳,这个值与系统时间无关,用来做seq值越界重新从0开始计算时,确认包顺序;ecr 1559458260 这个值用来计算RTT
length 759:这个值表示应用层传来数据的大小(不包括TCP header),与上面seq 4076194384:4076195143相减对应。
最后附上一个带完整数据的请求抓包(与上面抓包对应)
tcpdump -i lo -n port 8080 -SAl
- 15:56:45.608564 IP 127.0.0.1.49075 > 127.0.0.1.8080: Flags [S], seq 3763193645, win 43690, options [mss 65495,sackOK,TS val 1559364535 ecr 0,nop,wscale 7], length 0
- ..............E..<..@.@.x............-.M.-.........0.........
- \...........
- 15:56:45.608581 IP 127.0.0.1.8080 > 127.0.0.1.49075: Flags [S.], seq 3127397756, ack 3763193646, win 43690, options [mss 65495,sackOK,TS val 1559364535 ecr 1559364535,nop,wscale 7], length 0
- ..............E..<..@.@.<..........-...hM|.M.......0.........
- \...\.......
- 15:56:45.608595 IP 127.0.0.1.49075 > 127.0.0.1.8080: Flags [.], ack 3127397757, win 342, options [nop,nop,TS val 1559364535 ecr 1559364535], length 0
- ..............E..4..@.@.x&...........-.M...hM}...V.(.....
- \...\...
- 15:56:45.608705 IP 127.0.0.1.49075 > 127.0.0.1.8080: Flags [P.], seq 3763193646:3763194405, ack 3127397757, win 342, options [nop,nop,TS val 1559364535 ecr 1559364535], length 759
- ..............E..+..@.@.u............-.M...hM}...V. .....
- \...\...GET /rest/ee7d191e/get?page=1&start=0&limit=15 HTTP/1.1
- x-real-ip: 172.16.70.33
- remote-host: 172.16.70.33
- x-forwarded-for: 172.16.70.33
- user-agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36
- x-requested-with: XMLHttpRequest
- accept: */*
- referer: http://172.16.70.22/ui
- accept-encoding: gzip, deflate
- accept-language: zh-CN,zh;q=0.9
- cookie: connect.sid=s%3AYbFf2HMeIBrYNw-GY7PH86N0uqRa4Uda.gCS1W0CXVkGAoJg52r7vBWeYvN0615vMSC%2F6aUuro0o
- connection: close
- user: administrator
- sid: YbFf2HMeIBrYNw-GY7PH860uqRa4Uda
- ip_address: 172.16.70.33
- content-length: 2
- Accept-Charset: utf-8
- Host: localhost:8080
-
- {}
- 15:56:45.608715 IP 127.0.0.1.8080 > 127.0.0.1.49075: Flags [.], ack 3763194405, win 354, options [nop,nop,TS val 1559364535 ecr 1559364535], length 0
- ..............E..4N.@.@............-...hM}.M.%...b.(.....
- \...\...
- 15:56:45.718585 IP 127.0.0.1.8080 > 127.0.0.1.49075: Flags [P.], seq 3127397757:3127397828, ack 3763194405, win 354, options [nop,nop,TS val 1559364645 ecr 1559364535], length 71
- ..............E..{N.@.@............-...hM}.M.%...b.o.....
- \..%\...HTTP/1.1 200 OK
- Content-Type: application/json
- content-length: 87
-
-
- 15:56:45.718595 IP 127.0.0.1.49075 > 127.0.0.1.8080: Flags [.], ack 3127397828, win 342, options [nop,nop,TS val 1559364645 ecr 1559364645], length 0
- ..............E..4..@.@.x$...........-.M.%.hM....V.(.....
- \..%\..%
- 15:56:45.718887 IP 127.0.0.1.8080 > 127.0.0.1.49075: Flags [P.], seq 3127397828:3127397915, ack 3763194405, win 354, options [nop,nop,TS val 1559364646 ecr 1559364645], length 87
- ..............E...N.@.@............-...hM..M.%...b.......
- \..&\..%{"result":{"errorDesc":"Successfully","errorCode":0},"list":[],"totalCount":0}
- 15:56:45.718897 IP 127.0.0.1.49075 > 127.0.0.1.8080: Flags [.], ack 3127397915, win 342, options [nop,nop,TS val 1559364646 ecr 1559364646], length 0
- ..............E..4..@.@.x#...........-.M.%.hN....V.(.....
- \..&\..&
- 15:56:45.719429 IP 127.0.0.1.49075 > 127.0.0.1.8080: Flags [F.], seq 3763194405, ack 3127397915, win 342, options [nop,nop,TS val 1559364646 ecr 1559364646], length 0
- ..............E..4..@.@.x"...........-.M.%.hN....V.(.....
- \..&\..&
- 15:56:45.719717 IP 127.0.0.1.8080 > 127.0.0.1.49075: Flags [F.], seq 3127397915, ack 3763194406, win 354, options [nop,nop,TS val 1559364646 ecr 1559364646], length 0
- ..............E..4N.@.@............-...hN..M.&...b.(.....
- \..&\..&
- 15:56:45.719732 IP 127.0.0.1.49075 > 127.0.0.1.8080: Flags [.], ack 3127397916, win 342, options [nop,nop,TS val 1559364646 ecr 1559364646], length 0
- ..............E..4..@.@.x!...........-.M.&.hN....V.(.....
- \..&\..&
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。