按照OSI网络分层模型,IP是网络层协议,TCP是传输层协议,而HTTP和MQTT是应用层的协议。在这三者之间, TCP是HTTP和MQTT底层的协议。大家对HTTP很熟悉,这里简要介绍下MQTT。MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议,有可能成为物联网的重要组成部分。该协议支持所有平台,几乎可以把所有联网物品和外部连接起来,被用来当做传感器的通信协议。

  1. HTTP的不足

    HTTP协议经过多年的使用,发现了一些不足,主要是性能方面的,包括:

    HTTP的连接问题,HTTP客户端和服务器之间的交互是采用请求/应答模式,在客户端请求时,会建立一个HTTP连接,然后发送请求消息,服务端给出应答消息,然后连接就关闭了。(后来的HTTP1.1支持持久连接)
    因为TCP连接的建立过程是有开销的,如果使用了SSL/TLS开销就更大。

    在浏览器里,一个网页包含许多资源,包括HTML,CSS,JavaScript,图片等等,这样在加载一个网页时要同时打开连接到同一服务器的多个连接。

    HTTP消息头问题,现在的客户端会发送大量的HTTP消息头,由于一个网页可能需要50-100个请求,就会有相当大的消息头的数据量。

    HTTP通信方式问题,HTTP的请求/应答方式的会话都是客户端发起的,缺乏服务器通知客户端的机制,在需要通知的场景,如聊天室,游戏,客户端应用需要不断地轮询服务器。

    而 WebSocket是从不同的角度来解决这些不足中的一部分。还有其他技术也在针对这些不足提出改进。

  2. WebSocket
    WebSocket则提供使用一个TCP连接进行双向通讯的机制,包括网络协议和API,以取代网页和服务器采用HTTP轮询进行双向通讯的机制。

    本质上来说,WebSocket是不限于HTTP协议的,但是由于现存大量的HTTP基础设施,代理,过滤,身份认证等等,WebSocket借用HTTP和HTTPS的端口。由于使用HTTP的端口,因此TCP连接建立后的握手消息是基于HTTP的,由服务器判断这是一个HTTP协议,还是WebSocket协议。 WebSocket连接除了建立和关闭时的握手,数据传输和HTTP没丁点关系了。

历时11年,WebSocket终于被批准成为IETF的建议标准:RFC6455.其前身是WHATWG (Web Hypertext Application Technology Working Group)的工作。而Web Socket的API,是W3C的工作。

WebSocket可以只打开一个到以外的端口,迫使越来越多的应用迁移到HTTP上来了。

11年的websocket草案的变迁中,有的浏览器支持的是旧版本的websocket,比如iPhone4上的safari使用的WebSocket是旧版的握手协议,那么就要使用就的握手协议来制做服务器端。如今只有Safari支持旧版本的协议,Chrome和Firefox最新版都已升级至Hybi-10(协议地址)。因此,我们再来看一下WebSocket新版协议Hybi-10。这次协议变更非常大,主要集中在握手协议和数据传输的格式上。

握手协议

我们先来看一下大致的区别:

  1. 最老的websocket草案标准中是没有安全key,草案7.5、7.6中有两个安全key,而现在的草案10中只有一个安全key,即将 7.5、7.6中http头中的"Sec-WebSocket-Key1″与"Sec-WebSocket-Key2″合并为了一个"Sec- WebSocket-Key"
  2. 把http头中Upgrade的值由"WebSocket"修改为了"websocket";http头中的"-Origin"修改为了"Sec-WebSocket-Origin";
  3. 增加了http头"Sec-WebSocket-Accept",用来返回原来草案7.5、7.6服务器返回给客户端的握手验证,原来是以内容的形式返回,现在是放到了http头中;另外服务器返回客户端的验证方式也有变化。

服务器生成验证的方式变化较大,我们来做一介绍。

旧版:

1 GET / HTTP/1.1
2 Upgrade: WebSocket
3 Connection: Upgrade
4 Host: 127.0.0.1:1337
5 Origin: http://127.0.0.1:8000
6 Cookie: sessionid=xxxx; calView=day; dayCurrentDate=1314288000000
7 Sec-WebSocket-Key1: cV`p1* 42#7  ^9}_ 647  08{
8 Sec-WebSocket-Key2: O8 415 8x37R A8   4
9 ;"######

旧版生成Token的方法如下:

取出Sec-WebSocket-Key1中的所有数字字符形成一个数值,这里是1427964708,然后除以Key1中的空格数目,得到一个数值,保留该数值整数位,得到数值N1;对Sec-WebSocket-Key2采取同样的算法,得到第二个整数N2;把N1和N2按照Big- Endian字符序列连接起来,然后再与另外一个Key3连接,得到一个原始序列ser_key。Key3是指在握手请求最后,有一个8字节的奇怪的字符串";"######",这个就是Key3。然后对ser_key进行一次md5运算得出一个16字节长的digest,这就是老版本协议需要的 token,然后将这个token附在握手消息的最后发送回Client,即可完成握手。

新版:

1 GET / HTTP/1.1
2 Upgrade: websocket
3 Connection: Upgrade
4 Host: 127.0.0.1:1337
5 Sec-WebSocket-Origin: http://127.0.0.1:8000
6 Sec-WebSocket-Key: erWJbDVAlYnHvHNulgrW8Q==
7 Sec-WebSocket-Version: 8
8 Cookie: csrftoken=xxxxxx; sessionid=xxxxx

新版生成Token的方法如下:

首先服务器将key(长度24)截取出来,如4tAjitqO9So2Wu8lkrsq3w==,用它和自定义的一个字符串(长度 36)258EAFA5-E914-47DA-95CA-C5AB0DC85B11连接起来,然后把这一字符串进行SHA-1算法加密,得到长度为20字节的二进制数据,再将这些数据经过Base64编码,最终得到服务端的密钥,也就是ser_key。服务器将ser_key附在返回值Sec- WebSocket-Accept后,至此握手成功。

WebSocket也有自己一套帧协议。数据报文格式如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

0                   1                   2                   3

01234567890123456789012345678901

+-+-+-+-+-------+-+-------------+-------------------------------+

|F|R|R|R|opcode|M|Payload len|    Extended payload length    |

|I|S|S|S|  (4)  |A|     (7)     |             (16/63)           |

|N|V|V|V|       |S|             |   (ifpayload len==126/127)   |

||1|2|3|       |K|             |                               |

+-+-+-+-+-------+-+-------------+---------------+

|     Extended payload length continued,ifpayload len==127  |

+---------------+-------------------------------+

|                               |Masking-key,ifMASK set to1  |

+-------------------------------+-------------------------------+

|Masking-key(continued)       |          Payload Data         |

+-----------------------------------------------+

:                     Payload Data continued...                :

+-------------------------------+

|                     Payload Data continued...                |

+---------------------------------------------------------------+

FIN:1位,用来表明这是一个消息的最后的消息片断,当然第一个消息片断也可能是最后的一个消息片断;

RSV1, RSV2, RSV3:
分别都是1位,如果双方之间没有约定自定义协议,那么这几位的值都必须为0,否则必须断掉WebSocket连接;

Opcode:4位操作码,定义有效负载数据,如果收到了一个未知的操作码,连接也必须断掉,以下是定义的操作码:

  • %x0 表示连续消息片断
  • %x1 表示文本消息片断
  • %x2 表未二进制消息片断
  • %x3-7 为将来的非控制消息片断保留的操作码
  • %x8 表示连接关闭
  • %x9 表示心跳检查的ping
  • %xA 表示心跳检查的pong
  • %xB-F 为将来的控制消息片断的保留操作码

Mask:1位,定义传输的数据是否有加掩码,如果设置为1,掩码键必须放在masking-key区域,客户端发送给服务端的所有消息,此位的值都是1;

Payload length: 传输数据的长度,以字节的形式表示:7位、7+16位、或者7+64位。如果这个值以字节表示是0-125这个范围,那这个值就表示传输数据的长度;如果这个值是126,则随后的两个字节表示的是一个16进制无符号数,用来表示传输数据的长度;如果这个值是127,则随后的是8个字节表示的一个64位无符合数,这个数用来表示传输数据的长度。多字节长度的数量是以网络字节的顺序表示。负载数据的长度为扩展数据及应用数据之和,扩展数据的长度可能为0,因而此时负载数据的长度就为应用数据的长度。

Masking-key:0或4个字节,客户端发送给服务端的数据,都是通过内嵌的一个32位值作为掩码的;掩码键只有在掩码位设置为1的时候存在。
Payload data:  (x+y)位,负载数据为扩展数据及应用数据长度之和。
Extension data:x位,如果客户端与服务端之间没有特殊约定,那么扩展数据的长度始终为0,任何的扩展都必须指定扩展数据的长度,或者长度的计算方式,以及在握手时如何确定正确的握手方式。如果存在扩展数据,则扩展数据就会包括在负载数据的长度之内。
Application data:y位,任意的应用数据,放在扩展数据之后,应用数据的长度=负载数据的长度-扩展数据的长度。

三、 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是轻量级基于代理的发布/订阅的消息传输协议,设计思想是开放、简单、轻量、易于实现。这些特点使它适用于受限环境。例如,但不仅限于此:

  • 网络代价昂贵,带宽低、不可靠。
  • 在嵌入设备中运行,处理器和内存资源有限。

该协议的特点有:

  • 使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合。
  • 对负载内容屏蔽的消息传输。
  • 使用 TCP/IP 提供网络连接。
  • 有三种消息发布服务质量:
  • "至多一次",消息发布完全依赖底层 TCP/IP 网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。
  • "至少一次",确保消息到达,但消息重复可能会发生。
  • "只有一次",确保消息到达一次。这一级别可用于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果。
  • 小型传输,开销很小(固定长度的头部是 2 字节),协议交换最小化,以降低网络流量。
  • 使用 Last Will 和 Testament 特性通知有关各方客户端异常中断的机制。

早在1999年,IBM的Andy Stanford-Clark博士以及Arcom公司ArlenNipper博士发明了MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)技术。BM和St. Jude医疗中心通过MQTT开发了一套Merlin系统,该系统使用了用于家庭保健的传感器。St. Jude医疗中心设计了一个叫做Merlin@home的心脏装置,这种无限发射器可以用来监控那些已经植入复律-除颤器和起搏器(两者都是基本的传感器)的心脏病人。

该产品利用MQTT把病人的即时更新信息传给医生/医院,然后医院进行保存。这样的话,病人就不用亲自去医院检查心脏仪器了,医生可以随时查看病人的数据,给出建议,病人在家里就可以自行检查。

IBM称该发射器包括一个大型触摸屏,一个嵌入式键盘平台,以及一个Linux操作系统。

在未来几年,MQTT的应用会越来越广,值得关注。

通过MQTT协议,目前已经扩展出了数十个MQTT服务器端程序,可以通过PHP,JAVA,Python,C,C#等系统语言来向MQTT发送相关消息。

此外,国内很多企业都广泛使用MQTT作为Android手机客户端与服务器端推送消息的协议。其中Sohu,Cmstop手机客户端中均有使用到MQTT作为消息推送消息。据Cmstop主要负责消息推送的高级研发工程师李文凯称,随着移动互联网的发展,MQTT由于开放源代码,耗电量小等特点,将会在移动消息推送领域会有更多的贡献,在物联网领域,传感器与服务器的通信,信息的收集,MQTT都可以作为考虑的方案之一。在未来MQTT会进入到我们生活的各各方面。

如果需要下载MQTT服务器端,可以直接去MQTT官方网站点击software进行下载MQTT协议衍生出来的各个不同版本。

MQTT和TCP、WebSocket的关系可以用下图一目了然:

MQTT协议专注于网络、资源受限环境,建立之初不曾考虑WEB环境。HTML5 Websocket是建立在TCP基础上的双通道通信,和TCP通信方式很类似,适用于WEB浏览器环境。虽然MQTT基因层面选择了TCP作为通信通道,但我们添加个编解码方式,MQTT over Websocket也可以的。这样做的好处,MQTT的使用范畴被扩展到HTML5、桌面端浏览器、移动端WebApp、Hybrid等,多了一些想像空间。这样看来,无论是移动端,还是WEB端,MQTT都会有自己的使用空间。

一步一步学WebSocket (一) 初识WebSocket

一步一步学WebSocket(二) 使用SuperWebSocket实现自己的服务端

.NET 的 WebSocket 开发包比较

Websocket全讲解。跨平台的通讯协议!!基于websocket的高并发即时通讯服务器开发。

利用WebSocket传输数组或者Blob的方案

MQTT和WebSocket

http://channel9.msdn.com/coding4fun/blog/Machine-2-Machine-with-a-MQTT-Net-Library

MQ 遥测传输 (MQTT) V3.1 协议规范基于WebSocket 的MQTT
移动推送方案

IoT - Messaging with MQTT using Azure and .NET using netduino

MQTT V3.1----flow

MQTT协议简记

MQTT V3.1--我的理解

MQTT协议笔记之头部信息

MQTT协议笔记之连接和心跳

MQTT协议笔记之发布流程

MQTT协议笔记之消息流

MQTT协议笔记之订阅

MQTT 3.1.1,值得升级的6个新特性

MQTT学习笔记——MQTT协议体验 Mosquitto安装和使用

The Mosquitto MQTT broker gets Websockets support

A modern MQTT framework for .NET

https://github.com/somdoron/NetMQ.WebSockets

https://github.com/dude-seriously/gh12-server

TCP/IP, WebSocket 和 MQTT的更多相关文章

  1. TCP/IP WebSocket MQTT

    http://www.cnblogs.com/shanyou/p/4085802.html TCP/IP, WebSocket 和 MQTT

  2. TCP/IP Protocol Fundamentals Explained with a Diagram

    最近准备系统学习网络相关的知识,主要学习tcp/ip, websocket 知识. 原文地址:http://www.thegeekstuff.com/2011/11/tcp-ip-fundamenta ...

  3. TCP/IP,HTTP,HTTPS,WEBSocket协议

    我看看着挺多的,我暂时没时间自己写,有需要的请借鉴 http://mp.weixin.qq.com/s?__biz=MzI0MDQ4MTM5NQ==&mid=2247486927&id ...

  4. MQTT是IBM开发的一个即时通讯协议,构建于TCP/IP协议上,是物联网IoT的订阅协议,借助消息推送功能,可以更好地实现远程控制

    最近一直做物联网方面的开发,以下内容关于使用MQTT过程中遇到问题的记录以及需要掌握的机制原理,主要讲解理论. 背景 MQTT是IBM开发的一个即时通讯协议.MQTT构建于TCP/IP协议上,面向M2 ...

  5. C# HTTP1.0 1.1 2.0与HTTPS 、TCP/IP协议的UDP与TCP、 Socket介绍与WebSocket

    一.HTTP1.0 1.1 2.0和HTTPS 1.HTTP协议是什么? HTTP协议是超文本传输协议的缩写,英文是Hyper Text Transfer Protocol.它是从WEB服务器传输超文 ...

  6. 基于 WebSocket 的 MQTT 移动推送方案

    WebSphere MQ Telemetry Transport 简介 WebSphere MQ Telemetry Transport (MQTT) 是一项异步消息传输协议,是 IBM 在分析了他们 ...

  7. TCP/IP、HTTP、Socke、UDP的区别

    一.TCP/IP.Http.Socket的区别 [http://jingyan.baidu.com/article/08b6a591e07ecc14a80922f1.html](http://jing ...

  8. Http,Socket,TCP/IP 协议简述

    Http,Socket,TCP/IP 协议简述:https://blog.csdn.net/gordohu/article/details/54097841 TCP/IP协议,HTTP协议与webSo ...

  9. TCP/IP,UDP,HTTP,SOCKET之间的区别和关系

    TCP/IP TCP/IP代表传输控制协议/网际协议,指的是一系列协组.可分为四个层次:数据链路层.网络层.传输层和应用层. 在网络层:有IP协议.ICMP协议.ARP协议.RARP协议和BOOTP协 ...

随机推荐

  1. java中Inetaddress类

    InetAddress类 InetAddress类用来封装我们前面讨论的数字式的IP地址和该地址的域名. 你通过一个IP主机名与这个类发生作用,IP主机名比它的IP地址用起来更简便更容易理解. Ine ...

  2. Java面试常见知识点总结(二)

    11.构造方法(构造器): 构造方法是一种特殊的方法,具有以下特点.    (1) 构造方法的方法名必须与类名相同.    (2) 构造方法没有返回类型,也不能定义为void,在方法名前面不声明方法类 ...

  3. linux作业

    第二单元 (1)以root用户登录GNOME图形界面 语言支持选择为汉语 (2)使用快捷键切换到虚拟终端2,使用普通用户身份登录,查看系统提示符 (3)使用命令退出虚拟终端2上登录的用户 (4)使用快 ...

  4. git 查看某文件的修改历史

    前提 先进入此文件所在的目录下 1. git log filename可以看到fileName相关的commit记录2. git log -p filename可以显示每次提交的diff3. 只看某次 ...

  5. 在Myeclipse中提交代码到GitHub中

    这需要借助插件Egit,首先就是先下载该插件了,可以再eclipse中下载,也可以在外面下载,下载就不说了.下载地址git://github.com/houyongchao/plugin-Egit.g ...

  6. 写给Git初学者的7个建议

    [原文] - http://blog.jobbole.com/50603/ 当我刚刚开始使用Git的版本控制时,我根本不确定我付出那么多时间是不是会得到回报.Branch.Stage.Stash,这些 ...

  7. org.openqa.selenium.remote.SessionNotFoundException: Unexpected error launch IE

    1.在启动ie浏览器前先加入属性设置一项: DesiredCapabilities ie = DesiredCapabilities.internetExplorer(); ie.setCapabil ...

  8. Problem of saving images in WPF (RenderTargetBitmap)zz

      To save a visual to an image file need to use RenderTargetBitmap, detail is reference to Save and ...

  9. GRU(Gated Recurrent Unit) 更新过程推导及简单代码实现

    GRU(Gated Recurrent Unit) 更新过程推导及简单代码实现 RNN GRU matlab codes RNN网络考虑到了具有时间数列的样本数据,但是RNN仍存在着一些问题,比如随着 ...

  10. BZOJ1527 : [POI2005]Pun-point

    求出重心,然后把所有点关于重心极角排序,极角相同的按到重心距离从大到小排序. 按极角序依次扫描,得到相邻两个向量的夹角以及长度之比,看成字符串. 若两个字符串循环同构,则两个点集相似,KMP判断即可. ...