ZeroMQ_官方文档C#示例

ZeroMQ—指导

由 iMatix 公司的首席执行官 Pieter Hintjens编写。感谢Bill Desmarais, Brian Dorsey, CAF, Daniel Lin, Eric Desgranges, Gonzalo Diethelm, Guido Goldstein, Hunter Ford, Kamil Shakirov, Martin Sustrik, Mike Castleman, Naveen Chawla,Nicola Peduzzi, Oliver Smith, Olivier Chamoux, Peter Alexander, Pierre Rouleau, Randy Dryburgh, John Unwin, Alex Thomas, rofl0r, Mihail Minkov, Jeremy Avnet, Michael Compton,and Zed Shaw 的贡献,也感谢 Stathis Sideris,因为 Ditaa.。请对所有的意见和勘误表进行问题跟踪。这个版本覆盖了 0MQ2.0 的版本,发表于周
二 2010 年 11 月 9 日,9 时 32 分 19 秒。

第一章——基础的东西

修理(fixing)这个世界

怎么解释 0MQ?有些人会说它的所有美好的事情。它是类固醇(steroids)上的套接字。
它像有路由的邮箱。它很快。别人想分享它的启蒙,当这一切变得越来越明显,人们开始
顿悟了。事情变得更简单。再也不复杂了。它打开了人们的思维。其他人喜欢通过做比较
的方式来解释。它更小,更简单,但是看起来仍然很熟悉。就我个人而言,我希望回忆起
我们为什么要开发 0MQ,因为,这是读者们也很想知道的问题。

编程是装扮成艺术的科学,因为我们中的大多数不了解软件的物理过程。如果学过这
方面的知识的话,也学的很少。软件的物理过程不是算法,数据结构,语言和抽象。这些
只是我们研发,使用,然后扔掉的工具。软件真正的物理过程实际上是人们的思维过程。

我们都有自己的局限性,当事情变的复杂的时候,我们希望一起协作,把大的问题分
成小的问题来处理。这就是科学的编程,开发人们能够理解和容易使用的模块。并且,人
们会一起协作来解决很大的问题。

我们生活在一个连通的世界,当代的软件必须引导这个世界。因此,未来的大型软件
的编连模块应该是连通的,并且是并行的。代码不能再是“强大而沉默”的。代码必须和
代码对话。代码必须是能交谈的,友善的,容易连通的。代码必须像人脑一样运行。万亿
的神经元彼此发送消息,一个没有中央控制的大规模并行网络,没有单点失败,能够解决
很困难的问题。毫无疑问,将来的代码将会运行的像人脑,因为,每个网络的终端都看起
来有些像人脑。

如果你做过一些关于线程,协议或者网络的工作,你就会意识到这是非常不可能的。
它是一个梦。当你真正处理生活中的情形时,甚至利用少量的套接字连接少量的程序都让
人不胜其烦。万亿?这个成本是没法想象的。连接计算机如此困难,所以,它的软件和技
术实现的费用达十几亿美元。

因此,我们现在的状况是,布线的能力比我们能够使用它的能力超前了几年。我们在
上世纪 80 年代遇到了软件危机,当时像 Fred Brooks 这样的人认为没有解决办法。免费的开
源软件解决了这次危机,让我们能够高效地分享知识。今天,我们遇到了另一个软件危机,但
是我们对这个话题谈论的不多。只有最大,最有钱的公司能够建立连接的应用程序。虽然有云
端运算网络,但是它是私有的。我们的数据 、知识从我们的电脑里消失,进入我们不能访问、
不能竞争的云网络。谁拥有我们的社会网络?相反,它像大型电脑革命。

我们把关于政治哲学的问题留给别的书来解决吧。问题是,因特网提供了大量代码能够连
接在一起的可能的同时,事实是对于我们中的大多数,都不能够实现它。因此,因为没有办法
连接代码,很多人们感兴趣的问题(如健康,教育,经济,运输等)仍然没有解决,也没有办
法连接人们的聪明来解决这些问题。

人们已经做过很多连接软件的尝试。因特网工程特别任务组制定了数以千记的规范,每个
规范解决部分问题。对应用开发人员来说,HTTP 可能是一个很简单的解决方案,但是它却可能
让问题变得更糟糕,它鼓励开发人员和工程师开发大型服务器和瘦的并且愚蠢的客户机。

因此,今天人们仍然通过原始 UDP 或者 TCP,专门的协议,HTTP,网络套接字来连接引
用程序。它仍然很困难,慢,难以升级,并且很集中。分布式 P2P 结构大多数只能是玩玩,不
能用于工作。有多少应用程序是使用 Skype 或者 Bittorrent 来交换数据的呢?

什么能够带我们回到科学的编程?为了修理(fixing)世界,我们需要做两件事。一件是,
解决这个普遍问题“如何在任何地方把任意的代码连接起来。”另一件是,用人们容易理解和
使用的简单的模块把它封装起来。

它听起来简单的荒谬。但可能它确实就是这么简单。它就是问题的所在。

用一百个字来描述 0MQ

0MQ 看起来像是嵌入的网络库,但行为像一个并发的框架。它提供带所有信息并且跨
各种传输协议如进程间,进程内,广播等的套接字给你。你可以用多种方式实现 N 对 N 的
套接字连接,如扇出,发布订阅,请求应答。它足够快,因此可以制作集群。他的异步输
入输出模式为你提供了可扩展的多核应用,用来处理异步消息任务。它提供很多语言的套
接字,并且能够在很多操作系统上运行.0MQ 是 iMatix 公司研发的,是开源协议。

一些假设

我们假设你使用的是最新版本的 0MQ,而且你是当今的 git 高手。我们假设你使用的是
Liux 系统或者类似的。我们假设你能够读懂 C 语言代码,因为我们的很多代码是用 C 语言
编写的。我们假设如果程序需要,当我们写常量如 PUSH 或者 SUBSCRIBER 你能够想的到
它们实际上是 ZMQ-PUSH 或者 ZMQ-SUBSCRIBER。

请求与响应

让我们开始写一些代码,我们当然是以世界你好这个例子开始。我们将会构造一个服
务器和一个客户机。客户机发送“HELLO”给服务器,将会得到响应“World”。这是服务器
程序,它在端口 5555 打开一个 0MQ 套接字,并在端口读取请求,并对每一个请求都以
“World”应答。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

using ZeroMQ;

namespace Examples
{
    static partial class Program
    {
        public static void HWServer(string[] args)
        {
            //
            // Hello World server
            //
            // Author: metadings
            //

            if (args == null || args.Length < 1)
            {
                Console.WriteLine();
                Console.WriteLine("Usage: ./{0} HWServer [Name]", AppDomain.CurrentDomain.FriendlyName);
                Console.WriteLine();
                Console.WriteLine("    Name   Your name. Default: World");
                Console.WriteLine();
                args = new string[] { "World" };
            }

            string name = args[0];

            // Create
            using (var context = new ZContext())
            using (var responder = new ZSocket(context, ZSocketType.REP))
            {
                // Bind
                responder.Bind("tcp://*:5555");

                while (true)
                {
                    // Receive
                    using (ZFrame request = responder.ReceiveFrame())
                    {
                        Console.WriteLine("Received {0}", request.ReadString());

                        // Do some work
                        Thread.Sleep(1);

                        // Send
                        responder.Send(new ZFrame(name));
                    }
                }
            }
        }
    }
}

套接字对 REQ-REP 是步伐一致的。客户机调用 ZMQ 发送函数,然后调用函数zmq_send(3),然后调用函数 zmq_recv(3),这是一个循环(或者如果需要的话只调用一次)。使用别的任何序列(如在一行发送两个消息)都会出错。类似的,服务器按照先调用函数zmq_recv(3),然后调用函数 zmq_send(3)的顺序,调用次数根据需要而定。0MQ 使用 C 语言作为参考语言,并且我们也用 C 语言作为例子。如果你是在线入读本文,这个例子下面的链接将会帮你转换为别的程序语言。让我们用 C++编写的相同的服务器程序作为对比。
这里写图片描述
*这个看起来简单得不现实。但是,一个 0MQ 套接字就是当你把一个通用的 TCP 套接
字,注入从苏维埃秘密核研究项目偷来的混合的放射性同位素,用上世纪 50 年代的宇宙射
线轰炸它,再把它放在一个有膨胀的肌肉凸出在弹性合成纤维里的拙劣伪装成神物的,脑
袋被药弄坏了的漫画书作者的手里得到的。0MQ 套接字是拯救网络世界的超级英雄。*

这里写图片描述

一次让几千个客户机向服务器发送请求,它也可以工作的很好,很快。试着玩玩,先打开
客户机,再打开服务器,看看它是怎么继续工作的,想一下这意味着什么。

让我简单的解释一下这两个程序实际上在干什么。他们创建了 0MQ 工作的环境,和套接字。
不要担心不懂这些词语的意思。你慢慢会明白的。服务器在端口 5555 绑定它的 REP(应答)。
服务器等待一个请求,在一个循环中,它每次都会用一个应答来响应。客户机发送一个请求并
且读取来自服务器的应答。

在幕后发生了很多事,但是我们程序员关心的是代码是否简短和令人满意,甚至在重
荷下它是否也不会经常崩溃掉。这是请求-应答模型,可能是 0MQ 中最简单的模型。它主
要用于远程过程调用和典型的客户-服务器模式。

关于字符串的小小的注意事项

除了字节的大小外,0MQ 对你发送的数据一无所知。这就意味着你有责任对它进行安
全的格式化,以便应用程序能够读回它。对象和复杂数据类型的安全格式化有专门的库比
如协议缓冲区来完成。但是,即使是字符串,你也应该小心。

在 C 语言或者一些其它语言,字符串是以一个空字节结尾的,在 Hello World 的例子中,
可以看到,我们把字符串和空字节一起发送。

zmq_msg_init_data (&request, “Hello”, 6, NULL, NULL);

但是,如果你用另外一种语言发送数据,它可能不需要包括最后的空字节。例如,当
我们用 Pathon 语言来发送相同的字符串。我们用下面的语句:

socket.send (“Hello”)

在线路上传输的是:

这里写图片描述

如果你从 C 语言程序读到的,你可能会获得像字符串的东西,可能碰巧表现的像个字
符串(很幸运,这五个字节后面恰好跟着一个空字节),但它不是一个正确的字符串。

这就意味着,如果你混合使用 C 语言和另外一种语言来编写 Hello World 的客户机服务
器程序,你很可能会得到奇怪的结果。事实上,我希望你得到奇怪的结果,因为这样会帮
助你理解这部分。

如果你接收到一个来自 0MQ 的字符串,是用 C 语言编写的,你不能轻易相信它是正确
结尾的。每次收到一个字符串,你都需要分配一个新的有多余字节空间的缓冲区,复制这
个字符串,并以一个空字符结尾。

因此,我们制定了规则, 0MQ 字符串是定长的,在线路上发送不会尾随着一个空字
节。最简单的情况(在我们的例子中,我们将会做这件事)一个 0MQ 字符串对应一个 0MQ
消息结构,如上图所示,包括长度和一些字节。

这个程序描述的是我们接收来自 0MQ 的字符串,并且把它作为一个有用的字符串传送
给应用程序的过程,使用的是 C 语言。

static char *
s_recv (void *socket) {
    char buffer [256];
    int size = zmq_recv (socket, buffer, 255, 0);
    if (size == -1)
        return NULL;
    if (size > 255)
        size = 255;
    buffer [size] = 0;
    return strdup (buffer);
}
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值