目录
使用了 Wireshark 进行抓包,用两个最常用的 curl 和 ping 命令来演示抓包情况,开启抓包。
## 先访问我自己的网站首页
curl https://zengzhiqin.kuaizhan.com
## 再查看我自己网站的地址
ping https://zengzhiqin.kuaizhan.com
Wireshark根据 ping 命令得到的地址进行条件过滤,得到上面两个命令所得到的包,主要有 TCP(https基于tcp协议)协议和 ICMP(ping命令是基于 ICMP 协议)协议的包,如下图所示:
抓包分析首部内容简单分析:
包通过传输层千辛万苦找到了机器,机器那么多应用,假如这个时候艾莉给洪世贤发微信撩sao,世贤开了 QQ 又开了微信,这个时候就靠端口号来区分不同服务,QQ和微信的端口号肯定不一样,因此才能消息才能正确找到微信应用。
数据分段传输过程中,序列号可以保证所有传输的数据按照正常的次序进行重组,而且通过确认保证数据传输的完整性。
序列号可以用来确定传输内容的位置,传输到哪一个字节了,接收端接收到好根据序列号进行重组数据。相对序列号和相对确认号是用来简化随机序列号和随机确认号的。
下一个请求包的序列号 = 上一个请求包序列号 + 数据长度
确认号就是用来确认回复哪个序列号的多大的数据包,所以Ack=请求包的Seq+数据长度
。并且通过确认序列号,确认号,数据长度的值,可以确定此数据包是否完整。
就是首部长度,因为首部除了 20 字节固定长度之外,还有选项部分,是可选可变长度,所以需要有个偏移量告诉数据首部长度位置。
此 6 bit 二进制没有用到
小说明:大写的表示状态,如ACK,小写的表示确认号,如Ack;
tcp是可靠传输,有接收缓存和发送缓存,缓存被叫做窗口,通过滑动窗口技术实现可靠传输(这个地方还挺复杂的,下一篇会写关于可靠传输和拥塞控制相关的)
用来保证 TCP 头和数据的内容在抵达目的时的正确性完整性
如果设置了 URG 位,这个域将被检查作为额外的指令,告诉 CPU 从数据包的哪里开始读取数据,优先处理此包的命令。插队打乱了原来的队伍顺序,把列宁同志的团队人员单独优先处理,需要记录下这部分人的信息,是这个团队的就先走。
可以规定最大数据报的长度为多少,还可以支持选择性的进行确认。
选项和填充一共40个字节,如果不够需要进行填充凑够了
洪世贤饰客户端,林品如饰服务端
三次交涉牵手建立婚姻牵手过程:
(客户端)世贤:品如,你好美客户端发起请求,头部设置为SYN为1表示他要请求建立连接,并且发送一个随机序列号x,此时世贤进入 SYN_SENT 求婚等待爱情状态;
SYN包:SYN=1, ACK=0, Seq=x
(服务端)品如:世贤,你好帅服务端接收到连接请求,头部设置SYN+ACK表示他要回应了,并且自己也随机生成一个序列号标识自己y,通过将ack确认号设置为客户端的请求序列号x +1 的方式来告诉请求的客户端他回应的是哪个客户端,因为可能有很多个客户端同时向他请求建立连接,进行相应回应,此时品如进入了 SYN_RCVD 收到求婚并且同意等待下一步指示状态
SYN+ACK包:SYN=1, ACK=1, Seq=y, Ack=x+1
(客户端)世贤:品如,我们结婚客户端接收到服务端回复之后,再次确认连接,头部设置为ACK表示他收到了服务端的确认请求现在进行确认,ACK为1表示他要进行确认了,ack=y+1=服务端的请求序列号+1,表示他确认的是服务端这个包的请求,seq=x+1因为上一个客户端请求序列号是x,这个请求包从 x+1 开始,此时世贤收到同意回复进入了宣布结婚 ESTABILSHED 状态, 品如收到了结婚请求也进入了结婚状态
ACK包:ACK=1, Seq=x+1, Ack=y+1
小结:
因为建立连接之前是没有数据传输的,但是 SYN,ACK 等状态需要占用一个序号,所以这个地方请求序列号加的数据都是1,建立连接之后有数据传输,序列号和确认号加的数据都会是数据的长度;
Ack=请求序列号+数据长度;
包的序列号Seq = 同一端上一个包的序列号+数据长度;
下一个包的Seq = 上一个应答包的Ack
涨姿势:
借助wireshark的分析工具,点击 wireshark 的 Statistic 下面的Follow Graph,能得到如下的分析图,也可以很直观的看到牵手分手以及序列号:
四次分手过程的序列号和确认号,和上面牵手是一样的分析,就不贴图了贴个世贤。
四次挥手过程(客户端)世贤:你不够骚
(服务端)品如:我的衣柜不好看吗
(服务端)品如:算了衣服你们玩,我去跳海
(客户端)世贤:你喜欢大海,我爱过你
这个分手过程读者自己看图吧,写下来太多了,注意看双方状态,序列号和确认号。
一般如果客户端给服务端发起一个请求,服务端回复了,一来一回就能表示网络是畅通的,可以发数据。那么为什么需要第三个数据包呢?
首先,客户端请求建立连接如果没有成功是会一直重试的,那么就会有多个建立连接请求。
世贤和品如的故事
世贤饰客户端A数据包,窃格瓦拉饰客户端B数据包,品如饰服务端
假如世贤第一次求爱之前先绕远路去美国买了束玫瑰花,然后 窃格瓦拉 从牢里出来了直接就去找品如求爱了,品如这时候答应了窃格瓦拉的求爱,品如等着和窃格瓦拉来约她看海;
然后世贤也到了,品如一看世贤好帅反正她没有结婚又答应了世贤的求爱,于是品如又等着世贤约她看海;
试想一下全世界男的都去找品如告白一次,那品如就有看不完的海了,主要原因是因为品如不知道哪一个男的是来真的
。所以需要有人求婚,也就是第三次确认,结婚了就不用和别的男的看海了,直接放弃掉别人。
如果只有两次,那么服务端回应了就算是建立了连接,但是服务端没法判断他回应的请求连接是否在使用
,这就会导致下面两种情况:
第一种是会造成很多无效连接资源不能释放。请求包因为网络慢耗时严重,客户端重复发了很多包,一段时间后这些包到了服务端回复建立起了很多不必要的连接,这些连接资源无法释放,三次牵手第三次再次确认之后服务端建立连接并且将其他的无效连接释放掉。
牵手容易分手难,都市的饮食男女应该都能感受到这点。
主要是因为服务端收到关闭请求之后,服务端的数据可能还没有传完,这个时候服务端会继续把数据传输完,然后再告诉客户端可以关闭了,客户端再关闭。
MSL指一个片段在网络中最大的存活时间,2MSL是两倍的MSL(Maximum Segment Lifetime),就是一个发送和一个回复所需的最大时间。
网络是不可靠的,如果最后的ACK包丢失了
然后客户端又已经关闭了,那么服务端还会一直发送 FIN 请求关闭但是没人理他,他就会一直发FIN,那么服务端就会一直持续发 FIN 从而没法关闭了。所以客户端需要再等2MSL,这段时间一来一回的路上再也没有 FIN 包过来了,因此客户端可以放心关闭了。
感觉自己在写剧本,满脑子都是品如的衣柜,有收获的老铁点赞
或者点在看
来鼓励一下作者吧,感谢观看~
下期预告: tcp流量控制和拥塞控制的实现
欢迎关注我的公众号看更多内容