前言
好歹我也是一个科班计算机专业出身的人啊,对于网络知识这块我绝对不能怂啊,特此写下这篇文章,干干干冲啊!!!!!!!!!!!!!!!!
很多人想到 TCP/UDP 第一印象如下
- TCP:是一种面向连接的,可靠的基于字节流的传输层控制协议
- UDP:一种不可靠的协议
那为什么TCP协议是可靠的?基于字节流传输又体现在哪呢?传输层又是干嘛的呢?面向连接又体现在哪?基于这些问题在计算机网络这门课程中可以得到很好的回答。于是我想到那是一个带着暮色点点的下午,略带倦意的我坐在教室第三排恍惚间听着计网老师正在讲OSI七层模型。
OSI模型
- 应用层 :不同通信程序需要个性化
- 表示层:对数据进行加密、解密操作(将数据转换成二进制数据)
- 会话层:进行会话间的连接(建立、终止管理应用程序间的会话)
- 传输控制层:建立主机应用程序间端到端间的连接
- 网络层:负责ip的路由以及寻址
- 链路层:将数据转换为二进制数据封装成数据帧
- 物理层:负责将二进制的数据在光纤或者电缆上进行传输
为什么要有OSI七层模型?
在早期我们的各个通讯厂商间都是在研发自己的产品,由于每个厂商都有自己的一套规范,使用我们的产品进行通讯那就只能和我们厂商开发的软件进行通讯,并不能和别的厂商的产品进行通讯,这样显得十分闭塞拥堵,而OSI的出现则是为了制定一套规范出来,让各个厂商遵循OSI的规范,从而实现互通的目的
趣味OSI解读
如果觉着以上概念还是很抽象下面我来举个例子,形象的来解释一下吧。小张有一部华为手机、小李有一部苹果手机。有一天小张心血来潮想亲小李一下,于是通过QQ(应用层)给小李发送了一个亲的表情包(表情包内容:我是天底下最帅的男人。经过表示层对表情包进行加密,在经过会话层建立俩个手机之间的连接),第二天小李收到了小张的消息(期间过程:通过小张ip寻址到小李mac地址,在表示层将消息转换成二进制数据,在传输控制层寻找到同一个网段的小李,在网络层将数据封装成数据包,经过数据链路层又被封装成帧,然后通过网线将数据传输给小李的电脑),很是开心于是想去小张家亲小张一下,但由于是网友并不知道小张家的地址,这怎么办呢?小李很着急,但是办法总比困难多,小李先是顺着网线解析出上面的数据帧先迷恋一会,然后获取小张的ip地址,通过发起一个ARP协议获取小张家的MAC地址,由于MAC地址是唯一的,然后通过MAC地址成功定位到了小张的家
TCP报文头格式
由于本人懒下面就拿一张网图来分析一下TCP的报文头格式吧.
- source port:本机端口号
- destination port:请求的目的主机的端口号
- sequence number:序列号(TCP是基于字节传输的,每个字节都会被标注一个序列号,用于断点重传、ACK等操作)假设发送数据包大小是 0-20个字节,那么sequence number == 20
- acknowledgment number(ack):回复确认的序列号(2台主机进行通讯传输数据的时候,需要告知对方接收到了哪些字节,哪些是没有接到,然后判断是否需要重传。比如收到了 0 - 999 的字节那么 acknowledgment number = 1000)期望对方继续发送的那个数据包的序列号 ,每次加一
- reserved:对 acknowledgment number 的一个标识位。
- ACK:ACK 为 0 时acknowledgment number(ack) 无效、为 1 时 ack有效。
- SYN:请求建立连接(对数据包的一个标识、对方同意建立连接则SYN=1)
- FIN:请求断开连接 (对数据包的一个标识、FIN =1表示此报文发送方发送的数据已经发送完毕)
- Window:窗口的大小(主机间一次能接收多少数据)
- seq:是数据包本身的序列号,每次加一
趣味TCP三次握手
其中三次握手发生在内核中,也就是在传输控制层中发生,小故事+图解 描述如下。
a和b是一对夫妻在闹离婚,a向b说我们离婚叭(a向b发起一个被syn标记的数据包,并且这个包的序列号为seq =s 发起一个建立连接的请求),然后b收到离婚这个消息,说好那我们离婚吧(b收到了a发过来序列号为 s 的数据包,且回复a一个被 SYN 标记的数据包且数据包序号 seq = o 、并且期望收到对方下次发送序号为 ack = s+1 数据包),然后a也收到了b同意离婚的消息,然后回复说:好的(a收到了b发来序列号为 o 的数据包,然后给b发送一个序列号为 seq = s+1 的数据包,到此达成共识,可以离婚了)。
小故事总结: 双方都有通知对方且都做出了应答,才算建立好了连接
tcp三次握手图解
由于三次握手是在内核中完成的,而我们的程序是不能对此直接进行操作的,对此三次握手会生成一个内存空间buffer,我们的程序只知道当存在内存空间buffer了,就有了连接,这个内存空间buff就是一些数据(就是一些字节)。到此三次握手介绍完毕。
TCP省去最后的一次握手可不可以?
简单来说就是为了防止一些无效报文导致TCP连接重新建立,详情如下: 假设有这么一种情况,主机甲想断开与主机乙的连接,主机甲向主机乙发起一条建立TCP连接的请求报文,由于网络波动滞留在网络中,主机甲又向主机乙发起一条建立TCP连接的请求经过2此握手成功建立了连接,并且完成了任务又要销毁连接了,此时网络恢复了,主机甲向主机乙第一次发起的建立TCP连接的那条请求报文成功到达主机乙,之后又会经历二次握手的过程,由于这条报文是无效的,所以不会在发送ACK确认报文,主机乙收不到确认报文自然甲乙也不会建立连接了,如果没有第三次握手这个无效的报文依然会强迫主机甲与主机乙建立连接
四次挥手详解
- ESTABLISHED:建立连接后的状态
- FIN-WAIT-1:在发送FIN报文后立马会进入FIN-WAIT-1状态,当得到ACK回复则进入FIN-WAIT-2状态
- FIN-WAIT-2:在发送FIN报文后收到ACK回复则进入FIN-WAIT-2状态
- TIME-WAIT:等待收到连接关闭的消息,等待2ms
- LAST-ACK:准备接收最后一个ACK
- CLOSE-WAIT:准备关闭状态
- CLOSE:关闭连接状态
主机甲从ESTABLISHED状态请求关闭连接,发送FIN=1、ACK=1的报文给主机乙,主机甲随即进入FIN-WAIT-1状态,主机乙从ESTABLISHED状态转变为CLOSE-WAIT状态,随即发送ACK=1回复主机甲:说我已经收到你请求关闭连接的信息了,同意主机甲关闭连接,主机甲进入FIN-WAIT-2状态(半关闭状态,关闭操作进行了一半),这时候主机乙也通知主机甲我要关闭连接了,发送 FIN=1、ACK=1 给状态为TIME-WAIT的主机甲,随即主机乙为 LAST-ACK 状态(等待主机甲回复),而主机甲此时为收到主机乙发过来的FIN=1、ACK=1,且回复及时在TMIE-WAIT时间间隔内,主机甲便回复一个数据包ACK给主机乙,随即主机甲关闭连接,主机乙收到消息也变为CLOSE状态关闭连接了,到此双方都断开了连接
三次?为什么要四次挥手?
简单来说就是为了防止一些无效的报文导致TCP连接关闭,详情如下: 主机甲发送关闭连接的请求给主机乙(主机甲),也是由于网络波动导致这条请求再次滞留在网络中,导致甲发送了二次请求给乙,并且成功关闭了TCP连接,之后网络通顺了,甲与乙又重新建立了连接,网络通顺,第一次发送的关闭连接的报文被乙接到了,如果没有四次挥手,那么重新建立好的连接会由于这条无效报文被关闭,有了第四次挥手,由于是无效报文,甲并不会发送确认关闭的报文给乙,这样也就不会由于无效的报文导致连接关闭了。
主机甲为什么要等待TIME-WAIT(2ms)?
确保第三次挥手的消息(FIN=1、ACK=1)主机甲能收的到,保证第四次挥手发送的ACK=1对方能够接收的到
TCP如何解决高并发带来的问题(流量控制)
流量控制:tcp报文头部包含了window属性,意思就是告知发送数据包的人,我一次只能接收这么多数据包,超过范围的数据包我概不接收,你下次还是得从我需求 ack 的位置的数据包开始发包。 下图配套图解:主机甲发起四次请求发包给主机乙,但是由于不知道主机乙一次能接收多大量的数据包,发了499大小的数据包给主机乙,之后得到主机乙的回应(主机甲啊你发过来 300-499 的数据包都被我拒绝接收了,我的window大小为300、且我下次期望收到你从300位置发送过来的数据包哦),之后主机甲学乖了,每次发送的数据包的量都是 300了
实战体验TCP三次握手与四次挥手过程
- 环境:mac、抓包工具tcpdump、curl命令
打开俩个终端一个负责抓包,一个负责发送请求,终端一运行如下命令(监听抓取80端口的数据包、或者是arp请求):
sudo tcpdump -nn -i en0 port 80 or arp
终端二使用curl命令发起一个访问百度的请求:
curl www.baidu.com
终端一成功抓取到数据包,图中标蓝色的即为TCP的三次握手
图中标蓝色的即为TCP的四次挥手
扩展之ARP请求
首先在TCP建立连接之前会发起一次ARP请求,去寻找目标主机MAC地址的过程,如果本地ARP缓存表中存在目标IP与目标主机MAC地址的映射关系,那么直接从缓存表中取就好了,并不会再次发起ARP请求。所谓得ARP请求指,已知目标主机的 ip地址进而获取目标主机的MAC地址的一个请求。
本地电脑ip为192.168.155.21
抓包查看ARP请求 首先192.168.155.21发起arp请求携带百度的ip去询问百度,请告诉我你的mac地址,然后百度回复一个ARP请求告诉192.168.155.21,我的mac地址是***
|