复盘HTTP/TCP/MQTT/CoAP协议

##项目经历:
物联网开发中经常与设备通信,多种设备我们不可能每个设备写一个通信工具的,所以我们可以写一个支持多个协议多个设备的模块,方便我们开发中灵活调用。我项目中经常和嵌入式打交道,嵌入式程序软件有自己的语言(类似C++),虽然语言不能直接互通,但是可以根据通信协议做通信,其实就是底层的进程通信IPC原理,我工作中常用的例如串口通信,Socket,TCP/IP,MQTT等协议,串口通信依赖于串口,当然也可以用软件生成虚拟串口,把虚拟串口映射到端口来收发数据,也就是TCP/UDP方式,做一个通信中转,更加丰富了程序通信的方式。其他比如MQTT等也都是进程通信,只不过它接口丰富,支持消息管理的方式,更加智能。

常见BUG就是粘包的问题,例如面试会被问到:聊聊TCP的粘包、拆包以及解决方案
> 引用原文链接:https://zhuanlan.zhihu.com/p/356225028
> 它指TCP协议中,发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。
> TCP是面向字节流的协议,就是没有界限的一串数据,本没有“包”的概念,“粘包”和“拆包”一说是为了有助于形象地理解这两种现象。
> 为什么UDP没有粘包?
> 粘包拆包问题在数据链路层、网络层以及传输层都有可能发生。日常的网络应用开发大都在传输层进行,由于UDP有消息保护边界,不会发生粘包拆包问题,因此粘包拆包问题只发生在TCP协议中。
> 粘包拆包发生场景
> 因为TCP是面向流,没有边界,而操作系统在发送TCP数据时,会通过缓冲区来进行优化,例如缓冲区为1024个字节大小。
> 如果一次请求发送的数据量比较小,没达到缓冲区大小,TCP则会将多个请求合并为同一个请求进行发送,这就形成了粘包问题。
> 如果一次请求发送的数据量比较大,超过了缓冲区大小,TCP就会将其拆分为多次发送,这就是拆包。
> 常见的解决方案
> 对于粘包和拆包问题,常见的解决方案有四种:
> 发送端将每个包都封装成固定的长度,比如100字节大小。如果不足100字节可通过补0或空等进行填充到指定长度;
> 发送端在每个包的末尾使用固定的分隔符,例如\r\n。如果发生拆包需等待多个包发送过来之后再找到其中的\r\n进行合并;例如,FTP协议;
> 将消息分为头部和消息体,头部中保存整个消息的长度,只有读取到足够长度的消息之后才算是读到了一个完整的消息;
> 通过自定义协议进行粘包和拆包的处理。

我自己在项目中也遇到过粘包,然后是通过服务端对数据流长度的匹配,还有标记位置来做判断,这些都可以进一步封装。参考下Netty:
> Netty对粘包和拆包问题的处理
> Netty对解决粘包和拆包的方案做了抽象,提供了一些解码器(Decoder)来解决粘包和拆包的问题。如:
> LineBasedFrameDecoder:以行为单位进行数据包的解码;
> DelimiterBasedFrameDecoder:以特殊的符号作为分隔来进行数据包的解码;
> FixedLengthFrameDecoder:以固定长度进行数据包的解码;
> LenghtFieldBasedFrameDecode:适用于消息头包含消息长度的协议(最常用);
> 基于Netty进行网络读写的程序,可以直接使用这些Decoder来完成数据包的解码。对于高并发、大流量的系统来说,每个数据包都不应该传输多余的数据(所以补齐的方式不可取),LenghtFieldBasedFrameDecode更适合这样的场景。

##简介:
> 1.TCP
> TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。
> 手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接。TCP协议可以对上层网络提供接口,使上层网络数据的传输建立在“无差别”的网络之上。
> 建立起一个TCP连接需要经过“三次握手”:
> 第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
> 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
> 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
> 握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。断开连接时服务器和客户端均可以主动发起断开TCP连接的请求,断开过程需要经过“四次握手”(过程就不细写了,就是服务器和客户端交互,最终确定断开)。
> 2.HTTP
> HTTP 协议:Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。
> HTTP协议即超文本传送协议(Hypertext Transfer Protocol ),是Web联网的基础,也是手机联网常用的协议之一,HTTP协议是建立在TCP协议之上的一种应用。
> HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。
> 1)在HTTP 1.0中,客户端的每次请求都要求建立一次单独的连接,在处理完本次请求后,就自动释放连接。
> 2)在HTTP 1.1中则可以在一次连接中处理多个请求,并且多个请求可以重叠进行,不需要等待一个请求结束后再发送下一个请求。
> 由于HTTP在每次请求结束后都会主动释放连接,因此HTTP连接是一种“短连接”,要保持客户端程序的在线状态,需要不断地向服务器发起连接请求。通常的 做法是即时不需要获得任何数据,客户端也保持每隔一段固定的时间向服务器发送一次“保持连接”的请求,服务器在收到该请求后对客户端进行回复,表明知道客 户端“在线”。若服务器长时间无法收到客户端的请求,则认为客户端“下线”,若客户端长时间无法收到服务器的回复,则认为网络已经断开。
> 3.SOCKET
> 套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。
> 应用层通过传输层进行数据通信时,TCP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要通过同一个 TCP协 议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了套接字(Socket)接口。应用层可以 和传输层通过Socket接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。
> 建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket ,另一个运行于服务器端,称为ServerSocket 。
> 套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。
> 服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。
> 客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
> 连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户 端,一旦客户端确认了此描述,双方就正式建立连接。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
> 4.UDP
> UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768是UDP的正式规范。UDP在IP报文的协议号是17。
> UDP协议与TCP协议一样用于处理数据包,在OSI模型中,两者都位于传输层,处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。UDP用来支持那些需要在计算机之间传输数据的网络应用。包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。UDP协议从问世至今已经被使用了很多年,虽然其最初的光彩已经被一些类似协议所掩盖,但即使在今天UDP仍然不失为一项非常实用和可行的网络传输层协议。
> 许多应用只支持UDP,如:多媒体数据流,不产生任何额外的数据,即使知道有破坏的包也不进行重发。当强调传输性能而不是传输的完整性时,如:音频和多媒体应用,UDP是最好的选择。在数据传输时间很短,以至于此前的连接过程成为整个流量主体的情况下,UDP也是一个好的选择。
> 5.MQTT
> MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它工作在 TCP/IP协议族上,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议,为此,它需要一个消息中间件 。
> MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其在,通过卫星链路通信传感器、偶尔拨号的医疗设备、智能家居、及一些小型化设备中已广泛使用。
> 6.双工
> 数据通信中,数据在线路上的传送方式可以分为单工通信、半双工通信和全双工通信三种。
> (1)单工通信信道是单向信道,发送端和接收端的身份是固定的,发送端只能发送信息,不能接收信息;接收端只能接收信息,不能发送信息,数据信号仅从一端传送到另一端,即信息流是单方向的。
> (2)半双工通信,即Half-duplex Communication。这种通信方式可以实现双向的通信,但不能在两个方向上同时进行,必须轮流交替地进行。也就是说,通信信道的每一段都可以是发送端,也可以是接收端。但同一时刻里,信息只能有一个传输方向。如日常生活中的例子有步话机通信,对讲机等。
> (3)全双工(Full Duplex)是 在微处理器与外围设备之间采用发送线和接受线各自独立的方法,可以使数据在两个方向上同时进行传送操作。指在发送数据的同时也能够接收数据,两者同步进行,这好像我们平时打电话一样,说话的同时也能够听到对方的声音。
> 原文链接:https://blog.csdn.net/qq_41854291/article/details/115721493

> 另外还有一种是CoAP协议
> CoAP是一个基于 REST 模型的网络传输协议。主要用于轻量级 M2M 通信。由于物联网中的很多设备都是资源受限型的,即只有少量的内存空间和有限的计算能力,所以传统的 HTTP 协议应用在物联网上就显得过于庞大而不适用,CoAP 应运而生。
> 就用户可见性而言,CoAP 模拟了 HTTP 协议,并从这个角度来看,读数传感器数据本质上是像做一个 HTTP 请求。
> CoAP 被认为是一种不会过时的技术协议,根据 Grtner 预测,500 亿台设备将会连接到互联网,未来进一步发展将迫切需要低成本、低能耗的设备。CoAP协议被设计用于与 10 kb RAM 一样的系统。
> CoAP 更有趣的功能之一是能够发现网络中的节点。这对于低功耗无线传感器网络的自治和自我修复设计非常有用。关于无线传感器网络的可扩展性问题,可以使用 CoAP 协议来发现节点常规的冗余。
> CoAP 是建立在 UDP 栈上,这是与 HTTP 或 MQTT 相比最主要的区别。它可以更加快速和更好的资源优化,而非资源密集型。
> 然而,在 CoAP 协议下 QoS 因素保持不变情况下,CoAP 相比 HTTP/MQTT 更加不可靠。但是 4 字节的头文件对于连续流系统如环境监测传感器网络是一个不错的选择。
> 原文链接:https://zhuanlan.zhihu.com/p/138725785

##各种协议区别分析:
> 1.SOCKET与TCP
> 创建Socket连接时,可以指定使用的传输层协议,Socket可以支持不同的传输层协议(TCP或UDP),当使用TCP协议进行连接时,该Socket连接就是一个TCP连接。

> 2.Socket与HTTP
> 由于通常情况下Socket连接就是TCP连接,因此Socket连接一旦建立,通信双方即可开始相互发送数据内容,直到双方连接断开。但在实际网络应用 中,客户端到服务器之间的通信往往需要穿越多个中间节点,例如路由器、网关、防火墙等,大部分防火墙默认会关闭长时间处于非活跃状态的连接而导 致 Socket 连接断连,因此需要通过轮询告诉网络,该连接处于活跃状态。
> 而HTTP连接使用的是“请求—响应”的方式,不仅在请求时需要先建立连接,而且需要客户端向服务器发出请求后,服务器端才能回复数据。
> 很多情况下,需要服务器端主动向客户端推送数据,保持客户端与服务器数据的实时与同步。此时若双方建立的是Socket连接,服务器就可以直接将数据传送给客户端;若双方建立的是HTTP连接,则服务器需要等到客户端发送一次请求后才能将数据传回给客户端,因此,客户端定时向服务器端发送连接请求,不仅可以保持在线,同时也是在“询问”服务器是否有新的数据,如果有就将数据传给客户端。

> 3.TCP与UDP
> 1.TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接。
> 2.TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付。
> 3.TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的。UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等) 。
> 4.每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
> 5.TCP首部开销20字节;UDP的首部开销小。
> 6.TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道。
> 7.速度:UDP要比TCP要快!

> 4.HTTP与MQTT
> 速度和交付
> 根据3G网络的测量结果,MQTT的吞吐量比HTTP快93倍。
> 此外,与HTTP相比,MQTT协议确保了高传输保证。有3个级别的服务质量:
> – 最多一次:保证尽力交付。
> – 至少一次:保证消息至少传送一次。但是消息也可以不止一次传递。
> – 恰好一次:保证每个消息只被对方接收一次
> MQTT还为用户提供Last will&Testament和Retained消息的选项。第一个意味着在客户端意外断开连接的情况下,所有订阅的客户端都将从代理获得消息。保留消息意味着新订阅的客户端将立即获得状态更新。
> HTTP协议没有这些功能。
> 复杂性和消息大小
> MQTT具有相当短的规范。只有CONNECT,PUBLISH,SUBSCRIBE,UNSUBSCRIBE和DISCONNECT类型对开发人员很重要。而HTTP规范要长得多。
> MQTT具有非常短的消息头,并且最小的包消息大小为2个字节。通过HTTP协议使用文本消息格式允许它组成冗长的标题和消息。它有助于消除麻烦,因为它可以被人类阅读,但同时它对于资源受限的设备是不必要的。
> 结论
> MQTT协议易于使用。对于未来的解决方案,响应时间,吞吐量,更低的电池和带宽使用率是第一位的,这一点至关重要。在间歇性连接的情况下,它也是完美的。
> HTTP是值得和可扩展的。IoT开发时,MQTT更适合。

5.CoAP与HTTP
比它轻量级,低功耗,自治和自我修复
基于UDP,快速和更好的资源优化
QoS(Quality of Service,服务质量)比 HTTP/MQTT 更加不可靠,但是头文件只有4个字节,只有MQTT一倍大。
##总结:
> UDP:无连接,不可靠,速度快
> TCP:是底层通讯协议,定义的是数据传输和连接方式的规范;面向连接,可靠,点对点,全双工
> HTTP:是应用层协议,定义的是传输数据的内容的规范;适合使用在性能好一些的终端上
> MQTT:适合IoT开发;为大量计算能力有限且工作在低带宽、不可靠网络的远程传感器和控制设备通讯而设计的一种协议。
> CoAP 适合传感器开发,是应用层协议,是一个基于 REST 模型的网络传输协议。比HTTP轻量级,建立在 UDP 栈上。
> TCP协议粘包拆包问题是因为TCP协议数据传输是基于字节流的,它不包含消息、数据包等概念,需要应用层协议自己设计消息的边界,即消息帧(Message Framing)。如果应用层协议没有使用基于长度或者基于终结符息边界等方式进行处理,则会导致多个消息的粘包和拆包。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值