- OSI七层协议
- TCP/UDP
- 粘包现象
- 解决粘包问题
1、OSI七层协议
- 应用层(7)
- 表示层(6)
- 会话层(5)
- 传输层(4)
- 网路层(3)
- 数据链路层(2)
- 物理层(第1层)
标准的是七层协议,而为了大部分程序员的开发,将OSI七层协议合并成了OSI五层协议,将其中的应用层、表示层、会话层合并成了应用层。所以,也可以叫,OSI五层协议(应用层、传输层、网络层、数据链路层、物理层)
1.1:在数据传输的过程中使用的是交流电:
- 直流电(稳定电压),发送的数据:11111111111
- 交流电(高低电压),发送的数据:0101011000。
- 所以只有交流电才能传输信号,表达出不同的数据信息
1.2:五层协议各自做的事
- 应用层
- 如电脑上的各种软件,如Python、QQ、酷狗等,供用户使用的。
- 传输层
- 预备如何传输,每个程序将使用的端口,拼接端口到信息中
- 使用到port
- TCP/UDP协议
- 四层交换机,四层路由器(剧本解析端口的功能)
- 网络层
- 拼接IP地址到信息中
- 使用到IP:(ipv4协议,ipv6协议)
- 路由器,三层交换机
- 数据链路层
- 拼接mac地址到信息中
- 使用到mac:(arp协议,通过ip地址找到mac地址)
- 二层交换机,网卡
- 物理层
- 转换成电压信号进行传输了
以上操作,就是一层一层的往下嵌套,所以,这也就是套接字(socket)的意义了。至于家中只需要安装一台路由器而不是使用交换机,是因为现在的路由器都已经具备了交换机的功能了,所以可以进行替代了。
2、TCP与UDP
2.1:TCP(打电话)
TCP协议就像打电话,需要占用通道,只能等对方(服务端)结束了上一个通话(连接)后,下一个电话(连接)才能进入
- 需要建立连接,然后才能通信---->这就是全双工通信
- 特点:可靠性高(不等于安全性高,是数据不容易丢失)、占用端口、效率低、实时性高、慢(没有得到回复客户端会一直进行请求)
- 应用:线下缓存高清视频、QQ远程连接、发邮件
- 关键:三次握手和四次挥手
- 三次握手:
- 第一次:客户端向服务端发送请求连接的信号(SYN信号)
- 第二次:服务端向客户端发送确认连接的信号(ACK信号),同时,向客户端发送请求连接的信号(SYN信号)
- 第三次:客户端向服务端发送确认连接的信号(ACK信号)
- 四次挥手:
- 第一次:服务端(客户端)向客户端(服务端)发送请求断开连接的信号(FIN信号)
- 第二次:客户端(服务端)向服务端(客户端)发送确认断开连接的信号(ACK信号)
- 第三次:客户端(服务端)向服务端(客户端)发送请求断开连接的信号(FIN信号)
- 第四次:服务端(客户端)向客户端(服务端)发送确认断开连接的信号(ACK信号)
- 这里四次挥手与三次握手不同的地方,三次握手是将确认信号和请求信号一并发送,而四次挥手是将这两次分开的,所以是有了四次挥手。
- 因为在服务端(客户端)向客户端(服务端)发送请求断开的时候,有可能客户端(服务端)还存在一部分数据没有发送完成。所以必须等到数据都发送完成之后,才会进行双向的确认断开。也就是为了防止数据不完整,没发生完成的情况。所以也就不能将两个操作合并
- 三次握手:
2.2:UDP协议:(发短信)
相对于用打电话来形容TCP协议的情况,那么UDP协议就可以用发短信来形容它。发短信,就可以不论对方是否在线或占线(打电话),你都是可以发送短信过去给对方。
- 不需要建立连接,就可以直接通信
- 不可靠(消息容易因为网络不稳定产生数据容易丢失)、不占用连接、效率高、快(不管对方在不在线,就可以直接发送数据)
- 应用:在线视频播放、QQ消息、微信消息
3、粘包现象
粘包现象只存在于TCP协议中出现。
- 概念:两条连续的消息,合并成一个消息,这就叫粘包现象
- 出现:不仅仅出现在客户端(接收端),也会出现在服务端(发送端,发送时已经粘在一起了)
- 操作系统中有一个缓存池,且缓存的时间也很多。但如果两条消息的长度很短,且间隔很短,由于一些优化算法就会将其合并成一条消息(如同生活中送快递,也是将快递整合之后才会进行一起发送,就是为了提高效率)
- 示意图:
- 原因:
- 在传输的过程中是以流式传输,那么就有一个特点,就是多条消息之间没有边界
- 并且还有相关的优化算法在计算
- 发送端出现的原因:多条消息数据很小很短,且发送的间隔时间很短
- 客户端出现的原因:多条消息接受不及时,同样在操作系统的缓存池中堆在一起被合并了
- 客户端举例:有可能上一条收到的消息是需要做一些很复杂耗时的指令,而TCP的特点就是需要等到上一条指令完成之后才能接受下一条指令。这就可能导致服务端发送了多条消息,而客户端还在处理上一条的消息,并没有及时的接收到后续的指令,导致消息数据被堆叠。所以这也就是没有办法从保证数据能够及时接受这点来改善的原因。
- TCP与UDP在传输数据时的区别
- 首先,无论TCP还是UDP在传输的过程中都会不可避免的要用到交换机,而交换机是会对传输的数据进行限制,一般是1500个字节左右(这个值是可以设置的,但是从计算机的健康使用来看1500是最合适的)。同时,在数据传输的过程中如果遇到多个交换机传输,那么字节限制还是以最小的带宽来决定的,而你只能设置自己的交换机但没办法设置别人的交换机。所以,一般不对这个值进行修改。
- 如在你发送QQ消息如果数据量过大,那么会提示你用文件的形式来发送。
- UDP:UDP是不需要建立连接就可以发送消息的,对应的,UDP是不能发送大的文件。
- TCP:TCP是需要建立连接才能通信的,并且是可以发送大文件的。
- TCP在传输的过程中使用了拆包的方法来传输数据(即,如果数据很大,它会将数据进行拆包,拆成很多个小块,然后再进行发送,对应的客户端也会发批次接收)
- 如果发送端发出的拆包数据是1、2、3、4个部分,那么接收端也会接收到1、2、3、4个部分。假设接收端只接收到1、2、4,丢失了3的部分数据信息。那么接收端会发送一条信息至发送端,发送端收到后会再发一次3给接收端。这也就是TCP协议可靠的原因之一,另外一个原因就是之前说到的三次握手,TCP是面向连接的。
- 而这样进行拆包,就是为了能够更加灵活的进行数据传输。以流式进行传输的,所以多条消息之间是没有边界的原因。
- 首先,无论TCP还是UDP在传输的过程中都会不可避免的要用到交换机,而交换机是会对传输的数据进行限制,一般是1500个字节左右(这个值是可以设置的,但是从计算机的健康使用来看1500是最合适的)。同时,在数据传输的过程中如果遇到多个交换机传输,那么字节限制还是以最小的带宽来决定的,而你只能设置自己的交换机但没办法设置别人的交换机。所以,一般不对这个值进行修改。
4、解决粘包问题:
很显然,粘包是因为多条消息数据之间没有边界所导致的,那么对数据进行边界的设置就可以避免这个情况的出现。即,你发的一条消息的长度是多少,那么我就接收多少,刚刚好,也就不会多接收其他的数据了。
- 如何确定对方发来的数据是多少?
- 第一条先发送数据的长度而不是数据本身。
- 然后接收端根据收到的数据长度来设置接收的数据长度。
- 如这个小代码这样,就可以完成一个边界的设置:
- 上面这样的代码是写死的,不方便,所以可以自定义一个协议,比如规定发送数据的长度在0-9999之间--->4个字节。
- 但以上的代码还存在没有设置10000以上的漏洞,这时候就可以使用Python内的另外一个模块struck。
- struck
- 它可以将2**31内的数字都转换为4个字节,即(-2147483647~+2147383647之间),也就代表着可以一次性传输2G以内的数据。
- 使用struck将数字转换为字节的代码、将字节转换为数字的代码:
- 应用:
- 逻辑: