-
Notifications
You must be signed in to change notification settings - Fork 6
/
index.html
1569 lines (1341 loc) · 91.2 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<!-- 2020-04-15 Wed 19:59 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>A tour of CPPZMQ, the C++ bindings to libzmq</title>
<meta name="generator" content="Org mode" />
<meta name="author" content="Brett Viren" />
<style type="text/css">
<!--/*--><![CDATA[/*><!--*/
.title { text-align: center;
margin-bottom: .2em; }
.subtitle { text-align: center;
font-size: medium;
font-weight: bold;
margin-top:0; }
.todo { font-family: monospace; color: red; }
.done { font-family: monospace; color: green; }
.priority { font-family: monospace; color: orange; }
.tag { background-color: #eee; font-family: monospace;
padding: 2px; font-size: 80%; font-weight: normal; }
.timestamp { color: #bebebe; }
.timestamp-kwd { color: #5f9ea0; }
.org-right { margin-left: auto; margin-right: 0px; text-align: right; }
.org-left { margin-left: 0px; margin-right: auto; text-align: left; }
.org-center { margin-left: auto; margin-right: auto; text-align: center; }
.underline { text-decoration: underline; }
#postamble p, #preamble p { font-size: 90%; margin: .2em; }
p.verse { margin-left: 3%; }
pre {
border: 1px solid #ccc;
box-shadow: 3px 3px 3px #eee;
padding: 8pt;
font-family: monospace;
overflow: auto;
margin: 1.2em;
}
pre.src {
position: relative;
overflow: visible;
padding-top: 1.2em;
}
pre.src:before {
display: none;
position: absolute;
background-color: white;
top: -10px;
right: 10px;
padding: 3px;
border: 1px solid black;
}
pre.src:hover:before { display: inline;}
/* Languages per Org manual */
pre.src-asymptote:before { content: 'Asymptote'; }
pre.src-awk:before { content: 'Awk'; }
pre.src-C:before { content: 'C'; }
/* pre.src-C++ doesn't work in CSS */
pre.src-clojure:before { content: 'Clojure'; }
pre.src-css:before { content: 'CSS'; }
pre.src-D:before { content: 'D'; }
pre.src-ditaa:before { content: 'ditaa'; }
pre.src-dot:before { content: 'Graphviz'; }
pre.src-calc:before { content: 'Emacs Calc'; }
pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
pre.src-fortran:before { content: 'Fortran'; }
pre.src-gnuplot:before { content: 'gnuplot'; }
pre.src-haskell:before { content: 'Haskell'; }
pre.src-hledger:before { content: 'hledger'; }
pre.src-java:before { content: 'Java'; }
pre.src-js:before { content: 'Javascript'; }
pre.src-latex:before { content: 'LaTeX'; }
pre.src-ledger:before { content: 'Ledger'; }
pre.src-lisp:before { content: 'Lisp'; }
pre.src-lilypond:before { content: 'Lilypond'; }
pre.src-lua:before { content: 'Lua'; }
pre.src-matlab:before { content: 'MATLAB'; }
pre.src-mscgen:before { content: 'Mscgen'; }
pre.src-ocaml:before { content: 'Objective Caml'; }
pre.src-octave:before { content: 'Octave'; }
pre.src-org:before { content: 'Org mode'; }
pre.src-oz:before { content: 'OZ'; }
pre.src-plantuml:before { content: 'Plantuml'; }
pre.src-processing:before { content: 'Processing.js'; }
pre.src-python:before { content: 'Python'; }
pre.src-R:before { content: 'R'; }
pre.src-ruby:before { content: 'Ruby'; }
pre.src-sass:before { content: 'Sass'; }
pre.src-scheme:before { content: 'Scheme'; }
pre.src-screen:before { content: 'Gnu Screen'; }
pre.src-sed:before { content: 'Sed'; }
pre.src-sh:before { content: 'shell'; }
pre.src-sql:before { content: 'SQL'; }
pre.src-sqlite:before { content: 'SQLite'; }
/* additional languages in org.el's org-babel-load-languages alist */
pre.src-forth:before { content: 'Forth'; }
pre.src-io:before { content: 'IO'; }
pre.src-J:before { content: 'J'; }
pre.src-makefile:before { content: 'Makefile'; }
pre.src-maxima:before { content: 'Maxima'; }
pre.src-perl:before { content: 'Perl'; }
pre.src-picolisp:before { content: 'Pico Lisp'; }
pre.src-scala:before { content: 'Scala'; }
pre.src-shell:before { content: 'Shell Script'; }
pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
/* additional language identifiers per "defun org-babel-execute"
in ob-*.el */
pre.src-cpp:before { content: 'C++'; }
pre.src-abc:before { content: 'ABC'; }
pre.src-coq:before { content: 'Coq'; }
pre.src-groovy:before { content: 'Groovy'; }
/* additional language identifiers from org-babel-shell-names in
ob-shell.el: ob-shell is the only babel language using a lambda to put
the execution function name together. */
pre.src-bash:before { content: 'bash'; }
pre.src-csh:before { content: 'csh'; }
pre.src-ash:before { content: 'ash'; }
pre.src-dash:before { content: 'dash'; }
pre.src-ksh:before { content: 'ksh'; }
pre.src-mksh:before { content: 'mksh'; }
pre.src-posh:before { content: 'posh'; }
/* Additional Emacs modes also supported by the LaTeX listings package */
pre.src-ada:before { content: 'Ada'; }
pre.src-asm:before { content: 'Assembler'; }
pre.src-caml:before { content: 'Caml'; }
pre.src-delphi:before { content: 'Delphi'; }
pre.src-html:before { content: 'HTML'; }
pre.src-idl:before { content: 'IDL'; }
pre.src-mercury:before { content: 'Mercury'; }
pre.src-metapost:before { content: 'MetaPost'; }
pre.src-modula-2:before { content: 'Modula-2'; }
pre.src-pascal:before { content: 'Pascal'; }
pre.src-ps:before { content: 'PostScript'; }
pre.src-prolog:before { content: 'Prolog'; }
pre.src-simula:before { content: 'Simula'; }
pre.src-tcl:before { content: 'tcl'; }
pre.src-tex:before { content: 'TeX'; }
pre.src-plain-tex:before { content: 'Plain TeX'; }
pre.src-verilog:before { content: 'Verilog'; }
pre.src-vhdl:before { content: 'VHDL'; }
pre.src-xml:before { content: 'XML'; }
pre.src-nxml:before { content: 'XML'; }
/* add a generic configuration mode; LaTeX export needs an additional
(add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
pre.src-conf:before { content: 'Configuration File'; }
table { border-collapse:collapse; }
caption.t-above { caption-side: top; }
caption.t-bottom { caption-side: bottom; }
td, th { vertical-align:top; }
th.org-right { text-align: center; }
th.org-left { text-align: center; }
th.org-center { text-align: center; }
td.org-right { text-align: right; }
td.org-left { text-align: left; }
td.org-center { text-align: center; }
dt { font-weight: bold; }
.footpara { display: inline; }
.footdef { margin-bottom: 1em; }
.figure { padding: 1em; }
.figure p { text-align: center; }
.equation-container {
display: table;
text-align: center;
width: 100%;
}
.equation {
vertical-align: middle;
}
.equation-label {
display: table-cell;
text-align: right;
vertical-align: middle;
}
.inlinetask {
padding: 10px;
border: 2px solid gray;
margin: 10px;
background: #ffffcc;
}
#org-div-home-and-up
{ text-align: right; font-size: 70%; white-space: nowrap; }
textarea { overflow-x: auto; }
.linenr { font-size: smaller }
.code-highlighted { background-color: #ffff00; }
.org-info-js_info-navigation { border-style: none; }
#org-info-js_console-label
{ font-size: 10px; font-weight: bold; white-space: nowrap; }
.org-info-js_search-highlight
{ background-color: #ffff00; color: #000000; font-weight: bold; }
.org-svg { width: 90%; }
/*]]>*/-->
</style>
<link rel="stylesheet" type="text/css" href="styles/readtheorg/css/htmlize.css"/>
<link rel="stylesheet" type="text/css" href="styles/readtheorg/css/readtheorg.css"/>
<script type="text/javascript" src="styles/lib/js/jquery.min.js"></script>
<script type="text/javascript" src="styles/lib/js/bootstrap.min.js"></script>
<script type="text/javascript" src="styles/lib/js/jquery.stickytableheaders.min.js"></script>
<script type="text/javascript" src="styles/readtheorg/js/readtheorg.js"></script>
<style> #content{max-width:1800px;}</style>
<style> p{max-width:800px;}</style>
<style> li{max-width:800px;}</style>
<script type="text/javascript">
/*
@licstart The following is the entire license notice for the
JavaScript code in this tag.
Copyright (C) 2012-2018 Free Software Foundation, Inc.
The JavaScript code in this tag is free software: you can
redistribute it and/or modify it under the terms of the GNU
General Public License (GNU GPL) as published by the Free Software
Foundation, either version 3 of the License, or (at your option)
any later version. The code is distributed WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
As additional permission under GNU GPL version 3 section 7, you
may distribute non-source (e.g., minimized or compacted) forms of
that code without the copy of the GNU GPL normally required by
section 4, provided you include this license notice and a URL
through which recipients can access the Corresponding Source.
@licend The above is the entire license notice
for the JavaScript code in this tag.
*/
<!--/*--><![CDATA[/*><!--*/
function CodeHighlightOn(elem, id)
{
var target = document.getElementById(id);
if(null != target) {
elem.cacheClassElem = elem.className;
elem.cacheClassTarget = target.className;
target.className = "code-highlighted";
elem.className = "code-highlighted";
}
}
function CodeHighlightOff(elem, id)
{
var target = document.getElementById(id);
if(elem.cacheClassElem)
elem.className = elem.cacheClassElem;
if(elem.cacheClassTarget)
target.className = elem.cacheClassTarget;
}
/*]]>*///-->
</script>
</head>
<body>
<div id="content">
<h1 class="title">A tour of CPPZMQ, the C++ bindings to libzmq</h1>
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#intro">Introduction</a>
<ul>
<li><a href="#orgc61499e">This document</a></li>
<li><a href="#org1b5c722">Project contents</a></li>
</ul>
</li>
<li><a href="#messages">Messages</a>
<ul>
<li><a href="#creating-messages">Creating messages</a></li>
<li><a href="#resetting-messages">Resetting the message</a></li>
<li><a href="#message-data">Accessing data in a message</a></li>
<li><a href="#message-metadata">Message metadata</a></li>
</ul>
</li>
<li><a href="#buffers">Buffers</a>
<ul>
<li><a href="#orgbdc78d9">Buffer types</a></li>
<li><a href="#orgcc08f3c">Buffer construction</a></li>
<li><a href="#orgd2509b7">Buffer operations</a></li>
<li><a href="#orgea466aa">Access buffer data</a></li>
</ul>
</li>
<li><a href="#context">Context</a>
<ul>
<li><a href="#create-context">Creating a context</a></li>
<li><a href="#context-life">Context life cycle</a></li>
</ul>
</li>
<li><a href="#sockets">Socket</a>
<ul>
<li><a href="#socket-life">Socket life cycle</a></li>
<li><a href="#socket-link">Socket linkage</a></li>
<li><a href="#org3e50177">Sending</a></li>
<li><a href="#org3a79e67">Receiving</a></li>
<li><a href="#orgd077f1e">Socket options</a></li>
<li><a href="#org955cdae">Socket properties</a></li>
<li><a href="#orga25afc6">Socket references</a></li>
<li><a href="#orga0e439b">Socket handle</a></li>
</ul>
</li>
<li><a href="#monitor">Monitor</a></li>
<li><a href="#poller">Poller</a>
<ul>
<li><a href="#orgfa6c417"><code>zmq::poller_t</code></a></li>
<li><a href="#org8705484">Interlude</a></li>
<li><a href="#org2a8f3ae"><code>zmq::active_poller_t</code></a></li>
</ul>
</li>
<li><a href="#multipart">Multipart</a>
<ul>
<li><a href="#orgefd4893">Multiple messages</a></li>
<li><a href="#org447af4e">Multipart messages</a></li>
<li><a href="#codec">Codec</a></li>
</ul>
</li>
<li><a href="#org74f4fee">FIN</a></li>
</ul>
</div>
</div>
<div id="outline-container-org424b11d" class="outline-2">
<h2 id="intro">Introduction</h2>
<div class="outline-text-2" id="text-intro">
<p>
The <a href="https://zeromq.org/">ZeroMQ</a> project <a href="https://github.com/zeromq/cppzmq">cppzmq</a> provides C++ bindings for <a href="https://github.com/zeromq/libzmq/">libzmq</a>. With them we can exercise the power of ZeroMQ with idiomatic, modern C++. The bindings provide type safety, exception-based error reporting, the RAII approach to resource management. Most <b>cppzmq</b> functionality will work with C++11 and even older and here we consider features requiring C++17 and we ignore deprecated interfaces.
</p>
</div>
<div id="outline-container-orgc61499e" class="outline-3">
<h3 id="orgc61499e">This document</h3>
<div class="outline-text-3" id="text-orgc61499e">
<p>
In this document, I tour the main parts of the <b>cppzmq</b> package so I can learn them better. I write down what I learn along the way so maybe others can learn something too.
</p>
<p>
Brevity is attempted and so the general concepts of ZeroMQ are assumed to already be understood. If you, the curious reader, have not yet done so please do yourself a big favor and read the entire <a href="http://zguide.zeromq.org/">ZeroMQ Guide</a>. Read it at least twice. I think gets even better each time I read it as I find something new and useful that I had previously missed.
</p>
<p>
This tour may not be needed by everyone. We may make effective use of <b>cppzmq</b> simply by reading its header files and maybe checking the unit tests. In some cases we may also need to refer to the <b>libzmq</b> API documentation which should be installed on your system as Unix man pages (<code>man zmq</code> to start) and which are available <a href="http://api.zeromq.org/">online</a>. This document attempts to distill what was learned in the process of just such a reading. I hope it may serve as a gentle narrative or tour that will help others quickly feel comfortable developing with <b>cppzmq</b>.
</p>
<div class="note">
<p>
The source for this document may be found at <a href="https://github.com/brettviren/cppzmq-tour">https://github.com/brettviren/cppzmq-tour</a>. Corrections, particularly in the form of pull requests, are welcome.
</p>
</div>
</div>
</div>
<div id="outline-container-org1b5c722" class="outline-3">
<h3 id="org1b5c722">Project contents</h3>
<div class="outline-text-3" id="text-org1b5c722">
<p>
The <b>cppzmq</b> package core is a header-only library providing the C++ <code>namespace zmq::</code>. Currently the library consists of two headers and here is a summary of what they provide:
</p>
<dl class="org-dl">
<dt><a href="https://github.com/zeromq/cppzmq/blob/master/zmq.hpp"><code>zmq.hpp</code></a></dt><dd>(single part) message, context, buffer, socket, monitor, poller</dd>
<dt><a href="https://github.com/zeromq/cppzmq/blob/master/zmq_addon.hpp"><code>zmq_addon.hpp</code></a></dt><dd>multipart and related functions and another form of poller</dd>
</dl>
<p>
Most of the goodies are in <code>zmq.hpp</code> and we go through them in order they appear in that file. The goodies in <code>zmq_addon.hpp</code> are just as good and I feel there's no need for a separation. All my <b>cppzmq</b> projects benefit from both.
</p>
<p>
The package also provides substantial unit tests which can be mined for programming examples. The package <a href="https://github.com/zeromq/cppzmq/blob/master/README.md">README</a> file gives instructions for formal installation but one very simple option is copying the <code>zmq.hpp</code> and <code>zmq_addon.hpp</code> files right into our own package.
</p>
</div>
</div>
</div>
<div id="outline-container-org17f5d38" class="outline-2">
<h2 id="messages">Messages</h2>
<div class="outline-text-2" id="text-messages">
<p>
The <code>message_t</code> class from <code>zmq.hpp</code> is a C++ facade over an opaque <code>zmq_msg_t</code> from <b>libzmq</b>. It is conceptually equivalent to the <a href="http://czmq.zeromq.org/czmq4-0:zframe"><code>zframe(3)</code></a> from <a href="http://czmq.zeromq.org/">CZMQ</a>, the high level C bindings to <b>libzmq</b>. In ZeroMQ terms, <code>message_t</code> is a <i>single-part</i> message in that it holds a contiguous block of memory. Later, (sections <a href="#sockets">Socket</a> and <a href="#multipart">Multipart</a>) the idea of multiple single-part messages and multipart messages are covered.
</p>
</div>
<div id="outline-container-org0c76745" class="outline-3">
<h3 id="creating-messages">Creating messages</h3>
<div class="outline-text-3" id="text-creating-messages">
<p>
Here are some examples of constructing a <code>message_t</code>:
</p>
<div class="org-src-container">
<pre class="src src-c++"><span style="color: #73d216;">// </span><span style="color: #73d216;">Default constructs an empty message of size zero.</span>
<span style="color: #e9b2e3;">zmq</span>::<span style="color: #8cc4ff;">message_t</span> <span style="color: #fcaf3e;">msg</span>;
<span style="color: #73d216;">// </span><span style="color: #73d216;">Have message allocate some memory internally.</span>
<span style="color: #b4fa70;">const</span> <span style="color: #8cc4ff;">size_t</span> <span style="color: #fcaf3e;">size</span> = 1024;
<span style="color: #e9b2e3;">zmq</span>::<span style="color: #8cc4ff;">message_t</span> <span style="color: #fce94f;">msg</span>(size);
<span style="color: #73d216;">// </span><span style="color: #73d216;">Initialize internal memory with a copy of external data.</span>
<span style="color: #b4fa70;">const</span> <span style="color: #8cc4ff;">char</span> <span style="color: #fcaf3e;">bytes</span>[s] = {0};
<span style="color: #e9b2e3;">zmq</span>::<span style="color: #8cc4ff;">message_t</span> <span style="color: #fce94f;">msg</span>(bytes, size);
<span style="color: #73d216;">// </span><span style="color: #73d216;">Or, from string literal (see also str_buffer).</span>
<span style="color: #e9b2e3;">zmq</span>::<span style="color: #8cc4ff;">message_t</span> <span style="color: #fcaf3e;">msg</span>(<span style="color: #e9b96e;">"hello world!"</span>, 12);
<span style="color: #73d216;">// </span><span style="color: #73d216;">Initialize through iteration on a container.</span>
<span style="color: #e9b2e3;">std</span>::<span style="color: #8cc4ff;">vector</span><<span style="color: #8cc4ff;">int</span>> <span style="color: #fcaf3e;">ivec</span> = {1,2,3};
<span style="color: #e9b2e3;">zmq</span>::<span style="color: #8cc4ff;">message_t</span> <span style="color: #fce94f;">msg</span>(ivec.begin(), ivec.end());
<span style="color: #73d216;">// </span><span style="color: #73d216;">or more simply</span>
<span style="color: #e9b2e3;">zmq</span>::<span style="color: #8cc4ff;">message_t</span> <span style="color: #fce94f;">msg</span>(ivec);
<span style="color: #73d216;">// </span><span style="color: #73d216;">Zero-copy provision with custom deallocation callback.</span>
<span style="color: #73d216;">// </span><span style="color: #73d216;">Wraps zmq_msg_init_data(3), see man page for details.</span>
<span style="color: #e9b2e3;">zmq</span>::<span style="color: #8cc4ff;">message_t</span> <span style="color: #fcaf3e;">msg</span>(byte, size, myfree, <span style="color: #e9b2e3;">nullptr</span>);
<span style="color: #73d216;">// </span><span style="color: #73d216;">Move/swap the data of one message into a new one</span>
<span style="color: #e9b2e3;">zmq</span>::<span style="color: #8cc4ff;">message_t</span> <span style="color: #fce94f;">msg2</span>(msg);
<span style="color: #73d216;">// </span><span style="color: #73d216;">or</span>
<span style="color: #e9b2e3;">zmq</span>::<span style="color: #8cc4ff;">message_t</span> <span style="color: #fcaf3e;">msg2</span> = msg;
</pre>
</div>
</div>
</div>
<div id="outline-container-org7022afd" class="outline-3">
<h3 id="resetting-messages">Resetting the message</h3>
<div class="outline-text-3" id="text-resetting-messages">
<p>
We can also "rebuild" an existing message. The methods to do this mirror the constructor prototypes:
</p>
<div class="org-src-container">
<pre class="src src-c++"><span style="color: #73d216;">// </span><span style="color: #73d216;">Empty the message</span>
msg.rebuild();
<span style="color: #73d216;">// </span><span style="color: #73d216;">Allocate a new size</span>
msg.rebuild(size);
<span style="color: #73d216;">// </span><span style="color: #73d216;">Allocate and set with a copy</span>
msg.rebuild(bytes, size);
</pre>
</div>
<p>
Not included here is a zero-copy version similar to the zero-copy constructor shown above.
</p>
</div>
</div>
<div id="outline-container-org63f788c" class="outline-3">
<h3 id="message-data">Accessing data in a message</h3>
<div class="outline-text-3" id="text-message-data">
<p>
The message is a block of bytes and we can get at those bytes in a few ways:
</p>
<div class="org-src-container">
<pre class="src src-c++"><span style="color: #73d216;">// </span><span style="color: #73d216;">Size of the data in bytes </span>
<span style="color: #8cc4ff;">size_t</span> <span style="color: #fce94f;">msg</span>.size();
<span style="color: #73d216;">// </span><span style="color: #73d216;">Low level, type free access</span>
<span style="color: #b4fa70;">const</span> <span style="color: #8cc4ff;">void</span>* <span style="color: #fcaf3e;">vptr</span> = msg.data();
<span style="color: #73d216;">// </span><span style="color: #73d216;">As above but type cast</span>
<span style="color: #b4fa70;">const</span> <span style="color: #8cc4ff;">int</span>* <span style="color: #fcaf3e;">iptr</span> = msg.data<<span style="color: #8cc4ff;">int</span>>();
<span style="color: #73d216;">// </span><span style="color: #73d216;">With a copy into a non-const collection</span>
<span style="color: #e9b2e3;">std</span>::<span style="color: #8cc4ff;">vector</span> <span style="color: #fce94f;">ints</span>(msg.data<<span style="color: #8cc4ff;">int</span>>(), msg.size()/<span style="color: #b4fa70;">sizeof</span>(<span style="color: #8cc4ff;">int</span>));
<span style="color: #73d216;">// </span><span style="color: #73d216;">If the data makes sense as a string.</span>
<span style="color: #e9b2e3;">std</span>::<span style="color: #8cc4ff;">string</span> <span style="color: #fcaf3e;">str</span> = msg.to_string();
<span style="color: #73d216;">// </span><span style="color: #73d216;">And we can get a zero copy view.</span>
<span style="color: #e9b2e3;">std</span>::<span style="color: #8cc4ff;">string_view</span> <span style="color: #fcaf3e;">strv</span> = msg.to_string_view();
<span style="color: #73d216;">// </span><span style="color: #73d216;">An artistic string representation of the contents.</span>
<span style="color: #e9b2e3;">std</span>::cout << msg.str() << <span style="color: #e9b2e3;">std</span>::endl;
</pre>
</div>
</div>
</div>
<div id="outline-container-org06e1bd3" class="outline-3">
<h3 id="message-metadata">Message metadata</h3>
<div class="outline-text-3" id="text-message-metadata">
<p>
Here we have a few details that are specific to certain socket types. We still haven't gotten to sockets, but they are coming. You may feel comfortable to skip this section for now.
</p>
</div>
<div id="outline-container-orgfcc089f" class="outline-4">
<h4 id="orgfcc089f">SERVER Routing ID</h4>
<div class="outline-text-4" id="text-orgfcc089f">
<p>
When we receive and send messages via a socket of type <b>SERVER</b> our application must manage a "routing ID" in order to associate the messages with a remote <b>CLIENT</b> socket. We do this by getting and setting this ID from/on the message as:
</p>
<div class="org-src-container">
<pre class="src src-c++"><span style="color: #73d216;">// </span><span style="color: #73d216;">After we receive a message, remember its routing ID:</span>
<span style="color: #8cc4ff;">uint32_t</span> <span style="color: #fcaf3e;">rid</span> = msg.routing_id();
<span style="color: #73d216;">// </span><span style="color: #73d216;">Later, just before sending, we make sure to set the ID:</span>
<span style="color: #e9b2e3;">zmq</span>::<span style="color: #8cc4ff;">message_t</span> <span style="color: #fcaf3e;">msg2</span>;
msg2.set_routing_id(rid);
</pre>
</div>
<p>
In this example, two messages are used. If the received message is reused for the subsequent send, and we have not rebuilt it, the routing ID is retained and no explicit get/set is required.
</p>
</div>
</div>
<div id="outline-container-org0502cd7" class="outline-4">
<h4 id="org0502cd7">Broadcast Groups</h4>
<div class="outline-text-4" id="text-org0502cd7">
<p>
The <b>RADIO/DISH</b> sockets have a concept similar to <b>SERVER/CLIENT</b> routing ID and <b>PUB/SUB</b> <i>topics</i> which is that of a named <i>group</i> to which messages are associated. This group name may be set on and retrieved from the message.
</p>
<div class="org-src-container">
<pre class="src src-c++"><span style="color: #73d216;">// </span><span style="color: #73d216;">16 byte max including null '\0' terminator char</span>
<span style="color: #b4fa70;">const</span> <span style="color: #8cc4ff;">char</span>* <span style="color: #fcaf3e;">grp</span> = <span style="color: #e9b96e;">"hello world!"</span>;
msg.set_group(grp);
<span style="color: #73d216;">// </span><span style="color: #73d216;">Get the group name.</span>
grp = msg.group();
</pre>
</div>
</div>
</div>
<div id="outline-container-org6174942" class="outline-4">
<h4 id="org6174942">Metadata Properties</h4>
<div class="outline-text-4" id="text-org6174942">
<p>
More generally, messages may carry per-connection metadata "properties". The key and values for these are of type string. We'll describe how these may be set through <a href="#sockets">socket options</a> later but for now here is an example of how properties may be retrieved.
</p>
<div class="org-src-container">
<pre class="src src-c++"><span style="color: #73d216;">// </span><span style="color: #73d216;">Get system property </span>
<span style="color: #b4fa70;">const</span> <span style="color: #8cc4ff;">char</span>* <span style="color: #fcaf3e;">stype</span> = msg.gets(<span style="color: #e9b96e;">"Socket-Type"</span>);
<span style="color: #73d216;">// </span><span style="color: #73d216;">Get an application property</span>
<span style="color: #b4fa70;">const</span> <span style="color: #8cc4ff;">char</span>* <span style="color: #fcaf3e;">color</span> = msg.gets(<span style="color: #e9b96e;">"X-Favorite-Color"</span>);
</pre>
</div>
<p>
This <code>gets()</code> method wraps <a href="http://api.zeromq.org/master:zmq_msg_gets"><code>zmq_msg_gets(3)</code></a> so see that man page for details.
</p>
</div>
</div>
</div>
</div>
<div id="outline-container-org3ff15c7" class="outline-2">
<h2 id="buffers">Buffers</h2>
<div class="outline-text-2" id="text-buffers">
<p>
In <b>cppzmq</b>, a buffer is like a message, but different. It allows us another way to transmit data without creating a message or to gives us easier ways to create a message from our data.
</p>
</div>
<div id="outline-container-orgbdc78d9" class="outline-3">
<h3 id="orgbdc78d9">Buffer types</h3>
<div class="outline-text-3" id="text-orgbdc78d9">
<p>
There are two variants of buffers, <code>mutable_buffer</code> and <code>const_buffer</code>. As the name suggests, the data given to the first may be modified while the data given to the second may not be.
</p>
</div>
</div>
<div id="outline-container-orgcc08f3c" class="outline-3">
<h3 id="orgcc08f3c">Buffer construction</h3>
<div class="outline-text-3" id="text-orgcc08f3c">
<p>
Either type of buffer may be constructed directly as in this example:
</p>
<div class="org-src-container">
<pre class="src src-c++"><span style="color: #73d216;">// </span><span style="color: #73d216;">Empty </span>
<span style="color: #8cc4ff;">mutable_buffer</span> <span style="color: #fce94f;">mbuf</span>();
<span style="color: #8cc4ff;">const_buffer</span> <span style="color: #fce94f;">cbuf</span>();
<span style="color: #73d216;">// </span><span style="color: #73d216;">Fodder data</span>
<span style="color: #b4fa70;">const</span> <span style="color: #8cc4ff;">size_t</span> <span style="color: #fcaf3e;">size</span> = 1024;
<span style="color: #8cc4ff;">void</span>* <span style="color: #fcaf3e;">ptr</span> = malloc(size);
<span style="color: #b4fa70;">const</span> <span style="color: #8cc4ff;">void</span>* <span style="color: #fcaf3e;">cptr</span> = ptr;
<span style="color: #73d216;">// </span><span style="color: #73d216;">With data</span>
<span style="color: #8cc4ff;">mutable_buffer</span> <span style="color: #fce94f;">mbuf</span>(ptr, size);
<span style="color: #8cc4ff;">const_buffer</span> <span style="color: #fce94f;">cbuf</span>(cptr, size);
</pre>
</div>
<p>
We are also given a variety of functions named <code>buffer()</code> to construct buffers in useful ways. We give some examples next and will see later some examples of how to use buffers in the sections <a href="#sockets">Socket</a> and <a href="#multipart">Multipart</a>.
</p>
<div class="org-src-container">
<pre class="src src-c++"><span style="color: #73d216;">// </span><span style="color: #73d216;">Fodder data from previous example</span>
<span style="color: #73d216;">// </span><span style="color: #73d216;">Basic construction</span>
<span style="color: #e9b2e3;">zmq</span>::<span style="color: #8cc4ff;">mutable_buffer</span> <span style="color: #fcaf3e;">mbuf</span> = <span style="color: #e9b2e3;">zmq</span>::buffer(ptr, size);
<span style="color: #e9b2e3;">zmq</span>::<span style="color: #8cc4ff;">const_buffer</span> <span style="color: #fcaf3e;">cbuf</span> = <span style="color: #e9b2e3;">zmq</span>::buffer(cptr, size);
<span style="color: #73d216;">// </span><span style="color: #73d216;">C array. </span>
<span style="color: #8cc4ff;">int</span> <span style="color: #fcaf3e;">data</span>[1024];
mbuf = <span style="color: #e9b2e3;">zmq</span>::buffer(data);
<span style="color: #73d216;">// </span><span style="color: #73d216;">C++ vector, std::array is similar</span>
<span style="color: #e9b2e3;">std</span>::<span style="color: #8cc4ff;">vector</span><<span style="color: #8cc4ff;">int</span>> <span style="color: #fce94f;">data</span>(size);
mbuf = <span style="color: #e9b2e3;">zmq</span>::buffer(data);
<span style="color: #73d216;">// </span><span style="color: #73d216;">C++ string and string literal</span>
<span style="color: #e9b2e3;">std</span>::<span style="color: #8cc4ff;">string</span> <span style="color: #fcaf3e;">str</span> = <span style="color: #e9b96e;">"hello world"</span>;
mbuf = <span style="color: #e9b2e3;">zmq</span>::buffer(str);
cbuf = <span style="color: #e9b2e3;">zmq</span>::str_buffer(<span style="color: #e9b96e;">"hello world"</span>);
</pre>
</div>
</div>
</div>
<div id="outline-container-orgd2509b7" class="outline-3">
<h3 id="orgd2509b7">Buffer operations</h3>
<div class="outline-text-3" id="text-orgd2509b7">
<p>
Once constructed, buffers are rather simple but we can operate on them to narrow their view of the underlying data.
</p>
<div class="org-src-container">
<pre class="src src-c++"><span style="color: #73d216;">// </span><span style="color: #73d216;">Truncate tail half, same works with const_buffer</span>
mbuf = <span style="color: #e9b2e3;">zmq</span>::buffer(mbuf, mbuf.size()/2);
<span style="color: #73d216;">// </span><span style="color: #73d216;">Truncate front half, etc cbuf.</span>
mbuf += mbuf.size()/2;
</pre>
</div>
<p>
Why do this narrowing? One very useful pattern is for an application to take some action based on the prefix or postfix of a message. This narrowing can be performed after this information is used and the remainder can be forwarded to an output socket. No copying needed.
</p>
</div>
</div>
<div id="outline-container-orgea466aa" class="outline-3">
<h3 id="orgea466aa">Access buffer data</h3>
<div class="outline-text-3" id="text-orgea466aa">
<p>
Unlike a message, a buffer has only a basic pair of methods to get back the original data and its size, reflecting any narrowing that occurred.
</p>
<div class="org-src-container">
<pre class="src src-c++"><span style="color: #8cc4ff;">void</span> *<span style="color: #fcaf3e;">vptr</span> = mbuf.data();
<span style="color: #8cc4ff;">size_t</span> <span style="color: #fcaf3e;">size</span> = mbuf.size();
</pre>
</div>
<p>
And, that's about it.
</p>
</div>
</div>
</div>
<div id="outline-container-org4f10d1c" class="outline-2">
<h2 id="context">Context</h2>
<div class="outline-text-2" id="text-context">
<p>
The <code>context_t</code> from <code>zmq.hpp</code> embodies an opaque <b>libzmq</b> context such as created by <a href="http://api.zeromq.org/master:zmq_ctx_new"><code>zmq_ctx_new(3)</code></a>. A context is used by ZeroMQ to collect and manage a set of sockets which the application creates on/in the context. The context is thread safe (unlike some sockets) and may be shared between threads without concern for locking at the application level.
</p>
</div>
<div id="outline-container-orgec4d119" class="outline-3">
<h3 id="create-context">Creating a context</h3>
<div class="outline-text-3" id="text-create-context">
<p>
Almost always we create the default context:
</p>
<div class="org-src-container">
<pre class="src src-c++"><span style="color: #e9b2e3;">zmq</span>::<span style="color: #8cc4ff;">context_t</span> <span style="color: #fcaf3e;">ctx</span>;
</pre>
</div>
<p>
A move constructor is also available. After construction, various context options may be set and queried and <b>cppzmq</b> provides <code>ctx.set()</code> and <code>ctx.get()</code> to do this. I have yet to use them but we may check <a href="http://api.zeromq.org/master:zmq_ctx_set"><code>zmq_ctx_set(3)</code></a> for anything interesting.
</p>
</div>
</div>
<div id="outline-container-org4990bda" class="outline-3">
<h3 id="context-life">Context life cycle</h3>
<div class="outline-text-3" id="text-context-life">
<p>
We can not copy a context but we can move. Typically, we will construct it, keep it alive as long as we need the sockets that we have created with it and if we need it in some other code context we may pass it by reference. Here is a contrived example.
</p>
<div class="org-src-container">
<pre class="src src-c++"><span style="color: #8cc4ff;">void</span> <span style="color: #fce94f;">run_app</span>(<span style="color: #e9b2e3;">zmq</span>::<span style="color: #8cc4ff;">context_t</span>& <span style="color: #fcaf3e;">ctx</span>);
<span style="color: #8cc4ff;">void</span> <span style="color: #fce94f;">main</span>()
{
<span style="color: #e9b2e3;">zmq</span>::<span style="color: #8cc4ff;">context_t</span> <span style="color: #fcaf3e;">ctx</span>;
run_app(ctx);
}
</pre>
</div>
<p>
In most applications, we will let the <code>context_t</code> destruct and that will tear down our sockets. We may also tear down even sooner:
</p>
<div class="org-src-container">
<pre class="src src-c++"><span style="color: #73d216;">// </span><span style="color: #73d216;">Cease any blocking operations in progress.</span>
ctx.shutdown();
<span style="color: #73d216;">// </span><span style="color: #73d216;">Do a shutdown, if needed and destroy the context.</span>
ctx.close();
</pre>
</div>
</div>
</div>
</div>
<div id="outline-container-org0af45bc" class="outline-2">
<h2 id="sockets">Socket</h2>
<div class="outline-text-2" id="text-sockets">
<p>
The heart of ZeroMQ is the socket and for it <b>cppzmq</b> supplies us with the class <code>socket_t</code>. There exists too much useful information on the intriguing variety of ZeroMQ sockets to repeat here. A concise and definitive source is <a href="http://api.zeromq.org/master:zmq_socket"><code>zmq_socket(3)</code></a>. Really, read that carefully as it answers a large fraction of questions I have had and see asked by others.
</p>
</div>
<div id="outline-container-org83354c1" class="outline-3">
<h3 id="socket-life">Socket life cycle</h3>
<div class="outline-text-3" id="text-socket-life">
<p>
To be useful, sockets must be created with a <b>context</b> (which we covered in section <a href="#context">Context</a>) and a socket type identifier. In <b>libzmq</b> the type is identified with an integer, usually as provided by a CPP macro like <code>ZMQ_PUB</code>. In <b>cppzmq</b> (in C++11) we may still use these macros or bare integers or we may use an <code>enum class socket_type</code>.
</p>
<div class="org-src-container">
<pre class="src src-c++"><span style="color: #b4fa70;">using</span> <span style="color: #b4fa70;">namespace</span> <span style="color: #e9b2e3;">zmq</span>;
<span style="color: #8cc4ff;">context_t</span> <span style="color: #fcaf3e;">ctx</span>;
<span style="color: #8cc4ff;">socket_t</span> <span style="color: #fce94f;">pub</span>(ctx, ZMQ_PUB);
<span style="color: #8cc4ff;">socket_t</span> <span style="color: #fce94f;">sub</span>(ctx, <span style="color: #e9b2e3;">socket_type</span>::sub);
</pre>
</div>
<p>
A default socket may be constructed and later swap guts with another socket through a move assignment. A socket may also be move-constructed. But we can not copy a socket.
</p>
<div class="caution">
<p>
Not just for <b>cppzmq</b>, we must take care that all ZeroMQ sockets besides <b>SERVER</b>, <b>CLIENT</b>, <b>RADIO</b> and <b>DISH</b> must not be used from any thread other than the one in which they were created. Some caveats apply but best thing is just don't do it.
</p>
</div>
<p>
When a socket destructs or if its <code>socket_t::close()</code> method is explicitly called, the underlying <b>libzmq</b> socket will be destroyed via <a href="http://api.zeromq.org/master:zmq_close"><code>zmq_close(3)</code></a>.
</p>
</div>
</div>
<div id="outline-container-org1961142" class="outline-3">
<h3 id="socket-link">Socket linkage</h3>
<div class="outline-text-3" id="text-socket-link">
<p>
ZeroMQ sockets link up with each other via transport addresses (see eg <a href="http://api.zeromq.org/master:zmq_tcp"><code>zmq_tcp(7)</code></a>, <a href="http://api.zeromq.org/master:zmq_ipc"><code>zmq_ipc(7)</code></a>, <a href="http://api.zeromq.org/master:zmq_inproc"><code>zmq_inproc(7)</code></a>). One or more sockets may "bind" to an address and one or more may "connect". At least one of each type of link must be made for messages to be exchanged. Other rules apply. For example, only certain socket types may intercommunicate and some socket types do not work with some transports. These rules are all general to <b>libzmq</b> (not just <b>cppzmq</b>). It's up to us to write applications that follow these rules while <b>cppzmq</b> provides us very simple ways to form the links.
</p>
<div class="org-src-container">
<pre class="src src-c++"><span style="color: #b4fa70;">const</span> <span style="color: #e9b2e3;">std</span>::<span style="color: #8cc4ff;">string</span> <span style="color: #fcaf3e;">addr</span> = <span style="color: #e9b96e;">"tcp://127.0.0.1:5678"</span>;
sock1.bind(addr);
sock2.connect(addr);
</pre>
</div>
<p>
Note the lack of return values. A <code>zmq::error_t</code> will be thrown if something goes wrong. The linkage may be kept for the entire life cycle of the sockets but some applications may want to explicitly undo these actions:
</p>
<div class="org-src-container">
<pre class="src src-c++">sock1.unbind(addr);
sock2.disconnect(addr);
</pre>
</div>
</div>
</div>
<div id="outline-container-org3e50177" class="outline-3">
<h3 id="org3e50177">Sending</h3>
<div class="outline-text-3" id="text-org3e50177">
<p>
We have several ways to send with <b>cppzmq</b> and several more which are deprecated. Here, let's focus on the preferred methods. The choice is to pass a <code>message_t</code> by lvalue reference or by rvalue reference or to pass a <code>const_buffer</code> by value In all cases we must also provide something called "send flags" which we will cover in a little bit
</p>
<div class="org-src-container">
<pre class="src src-c++"><span style="color: #e9b2e3;">zmq</span>::<span style="color: #8cc4ff;">message_t</span> <span style="color: #fcaf3e;">msg</span> = <span style="color: #fce94f;">...</span>;
<span style="color: #73d216;">// </span><span style="color: #73d216;">Pass by reference</span>
<span style="color: #b4fa70;">auto</span> <span style="color: #fcaf3e;">res</span> = sock.send(msg, <span style="color: #e9b2e3;">zmq</span>::<span style="color: #e9b2e3;">send_flags</span>::none);
<span style="color: #73d216;">// </span><span style="color: #73d216;">Pass by move</span>
<span style="color: #b4fa70;">auto</span> <span style="color: #fcaf3e;">res</span> = sock.send(<span style="color: #e9b2e3;">std</span>::move(msg), <span style="color: #e9b2e3;">zmq</span>::<span style="color: #e9b2e3;">send_flags</span>::none);
<span style="color: #73d216;">// </span><span style="color: #73d216;">Pass by buffer</span>
<span style="color: #b4fa70;">auto</span> <span style="color: #fcaf3e;">res</span> = sock.send(<span style="color: #e9b2e3;">zmq</span>::str_buffer(<span style="color: #e9b96e;">"hello world"</span>), <span style="color: #e9b2e3;">zmq</span>::<span style="color: #e9b2e3;">send_flags</span>::none);
</pre>
</div>
<p>
The first two call <a href="http://api.zeromq.org/master:zmq_msg_send"><code>zmq_msg_send(3)</code></a> and the last calls <a href="http://api.zeromq.org/master:msg_send"><code>msg_send(3)</code></a> so see those man pages for any nitty gritty details you may want.
</p>
</div>
<div id="outline-container-orgfc7301b" class="outline-4">
<h4 id="orgfc7301b">Send flags</h4>
<div class="outline-text-4" id="text-orgfc7301b">
<p>
ZeroMQ accepts a few "hints" on how it is to treat a message when sending. In <b>cppzmq</b> we may provide these with the <code>enum class</code> called <code>zmq::send_flags</code>. It is rare that I use anything other than <code>zmq::send_flags::none</code>, as shown in the example, but two more are available:
</p>
<dl class="org-dl">
<dt><code>dontwait</code></dt><dd>if the send may block instead return immediately with error <b>EAGAIN</b></dd>
<dt><code>sndmore</code></dt><dd>the message is to be sent together with a following message</dd>
</dl>
<p>
Details of the applicability and meaning of these flags are found in <a href="http://api.zeromq.org/master:zmq_msg_send"><code>zmq_msg_send(3)</code></a>.
</p>
</div>
</div>
<div id="outline-container-org701f951" class="outline-4">
<h4 id="org701f951">Send results</h4>
<div class="outline-text-4" id="text-org701f951">
<p>
That <code>auto res</code> holding the return of a <code>send()</code> in the example above is a <code>zmq::send_result_t</code> and that is a <code>std::optional</code> which may hold a <code>size_t</code> giving the number of bytes sent or nothing if <b>EAGAIN</b> error occurred and that only happens with a <code>dontwait</code> flag (see above).
</p>
<p>
Regardless of the send flag used we <b>must</b> save the send result in a variable because the <code>send()</code> methods are compiled marked with the C++ attribute <code>[[nodiscard]]</code>. We can be lazy and then do nothing with the <code>res</code> variable, but we should be more rigorous and compile with <code>-Wunused</code> (maybe via <code>-Wall</code>) so we can be told when we fail to use the <code>res</code> send result. Let's be even better and compile with <code>-Werror</code> to really force us to do something with it.
</p>
<p>
Regardless of what send flag we use, any other error that occurs will lead to a throw of the <code>zmq::error_t</code> exception so we do not require any special compiler flags to be sure all other errors can not go silently unchecked.
</p>
<div class="note">
<p>
One comment to give my preference. In most cases we will use <code>none</code>. The API would be friendlier to us if <code>none</code> was set as a default. However, that simpler call signature was already taken by other (now deprecated) versions of <code>send()</code>. Maybe in a future release, at the cost of a breaking change, this friendliness can be added!
</p>
</div>
</div>
</div>
<div id="outline-container-orgbdd567f" class="outline-4">
<h4 id="orgbdd567f">Send polling</h4>
<div class="outline-text-4" id="text-orgbdd567f">
<p>
At times our application may send messages faster than downstream applications can receive. Eventually, our socket's internal buffer will reach its "high water mark" (HWM) and enter what is called the "mute" state. What happens next depends on the socket types used and is explained in nice detail in <a href="http://api.zeromq.org/master:zmq_socket"><code>zmq_socket(3)</code></a>. We may elect to let that built-in behavior handle the issue or we may develop our application to be more proactive. For that, we can learn if the next message will tip our socket into "mute" step by polling it prior to output (pollout). A pollout is maybe not so commonly used compared to its opposite (pollin) which we will touch on in the next section and we will revisit polling in more detail in section <a href="#poller">Poller</a>.
</p>
</div>
</div>
</div>
<div id="outline-container-org3a79e67" class="outline-3">
<h3 id="org3a79e67">Receiving</h3>
<div class="outline-text-3" id="text-org3a79e67">
<p>
The opposite to sending to a socket is receiving from a socket. We may do this with <code>recv()</code>. The misspelling of this verb has a long history in network programming and ZeroMQ and <b>cppzmq</b> cheerfully continues it. Like with <code>send()</code>, we have one <code>recv()</code> method for a message one for a buffer and for both we give recv flags.
</p>
<div class="org-src-container">
<pre class="src src-c++"><span style="color: #73d216;">// </span><span style="color: #73d216;">Fill a message passed by reference</span>
<span style="color: #b4fa70;">auto</span> <span style="color: #fcaf3e;">res</span> = sock.recv(msg, <span style="color: #e9b2e3;">zmq</span>::<span style="color: #e9b2e3;">recv_flags</span>::none);
<span style="color: #73d216;">// </span><span style="color: #73d216;">Fill a suitably pre-sized mutable_buffer</span>
<span style="color: #b4fa70;">auto</span> <span style="color: #fcaf3e;">res</span> = sock.recv(buf, <span style="color: #e9b2e3;">zmq</span>::<span style="color: #e9b2e3;">recv_flags</span>::none);
</pre>
</div>
<p>
These two examples correspond to the low-level <a href="http://api.zeromq.org/master:zmq_msg_recv"><code>zmq_msg_recv(3)</code></a> and <a href="http://api.zeromq.org/master:zmq_recv"><code>zmq_recv(3)</code></a> respectively. When using the buffer to receive the data, take care that it has sufficient capacity to hold the expected message. The care you must take pays back in avoiding a copy.
</p>
</div>
<div id="outline-container-org95415bf" class="outline-4">
<h4 id="org95415bf">Receive flags</h4>
<div class="outline-text-4" id="text-org95415bf">
<p>
Like <code>send()</code>, <code>recv()</code> takes flags but with this method we may often want to specify a flag besides <code>none</code>. There is however only one other choice:
</p>
<dl class="org-dl">
<dt><code>dontwait</code></dt><dd>if the recv may block instead return immediately with error <b>EAGAIN</b></dd>
</dl>
<p>
This flag can be useful if our application wants to do a "quick check" to see if a message is waiting, and to receive it. If no message is sitting in the socket's input queue, the <code>recv()</code> will return immediately. If we use <code>none</code> then <code>recv()</code> may, in principle, wait until the end of the universe before returning.
</p>
</div>
</div>
<div id="outline-container-org4791db8" class="outline-4">
<h4 id="org4791db8">Receive results</h4>
<div class="outline-text-4" id="text-org4791db8">
<p>
Also like <code>send()</code>, our <code>recv()</code> returns a <code>std::optional</code> result which is empty if <b>EAGAIN</b> was returned by <b>libzmq</b>. Otherwise it returns the number of bytes received. And likewise, this return value also must be saved to a variable. The same comments about the importance to check this value as describe in the <a href="#org701f951">Send results</a> section apply here.
</p>
<p>
When we <code>recv()</code> with <code>message_t</code>, a non-empty receive result will hold the size in bytes of the message.
OTOH, when using a buffer, it is extra important to check the receive result. If non-empty it holds a <code>zmq::recv_buffer_size</code> which is a little <code>struct</code> holding two size attributes. The <code>size</code> says how much data we received and the <code>untruncated_size</code> tells us how much data ZeroMQ wanted to give us. If the two values differ we know our application failed to provide a large enough buffer. Oops.
</p>
</div>
</div>
<div id="outline-container-orgecf2b00" class="outline-4">
<h4 id="orgecf2b00">Receive polling</h4>
<div class="outline-text-4" id="text-orgecf2b00">
<p>
Depending on the receive flags we can either assure an immediate return from <code>recv()</code> or we may risk it never returning. That's a tough dichotomy to live with. Thankfully we can assure that the call waits at most some time in between those extremes using receive polling. This is discussed more below in the section <a href="#poller">Poller</a>.
</p>
</div>
</div>
</div>
<div id="outline-container-orgd077f1e" class="outline-3">
<h3 id="orgd077f1e">Socket options</h3>
<div class="outline-text-3" id="text-orgd077f1e">
<p>
Usually we develop an application that makes some ZeroMQ sockets, do our <code>bind()/connect()</code> and some <code>send()/recv()</code> and that's all we need for a lot of fun. There's not much detail to worry about. Sometimes we have a tough problem that needs something special and there's very likely a way that past ZeroMQ community members have found a solution. We then just need to find and set the right socket options.
</p>
<p>
The rather long list of possible options (85 counted today) are given in <a href="http://api.zeromq.org/master:zmq_setsockopt"><code>zmq_setsockopt(3)</code></a>. There they have names like <code>ZMQ_IMMEDIATE</code> or <code>ZMQ_ROUTING_ID</code> which are CPP macros expanding to some integer. For each, <b>cppzmq</b> creates a type tag to use with friendly <code>get()/set()</code> methods on <code>socket_t</code>.
</p>
<div class="org-src-container">
<pre class="src src-c++">sock.set(<span style="color: #e9b2e3;">zmq</span>::<span style="color: #e9b2e3;">sockopt</span>::immediate, <span style="color: #e9b2e3;">false</span>);
sock.set(<span style="color: #e9b2e3;">zmq</span>::<span style="color: #e9b2e3;">sockopt</span>::routing_id, <span style="color: #e9b96e;">"me"</span>);
<span style="color: #b4fa70;">auto</span> <span style="color: #fcaf3e;">rid</span> = sock.get(<span style="color: #e9b2e3;">zmq</span>::<span style="color: #e9b2e3;">sockopt</span>::routing_id);
</pre>
</div>
<p>
We will still need to carefully read <code>zmq_setsockopt</code> to discover and understand what options may help us, but then applying or querying them with a <b>cppzmq</b> socket is simple.
</p>
</div>
</div>
<div id="outline-container-org955cdae" class="outline-3">
<h3 id="org955cdae">Socket properties</h3>
<div class="outline-text-3" id="text-org955cdae">
<p>
One special socket option lets us set socket properties. These can be retrieved from messages that pass through the socket as described above in <a href="#message-metadata">Message metadata</a>.
</p>
<div class="org-src-container">
<pre class="src src-c++">sock.set(<span style="color: #e9b2e3;">zmq</span>::<span style="color: #e9b2e3;">sockopt</span>::metadata, <span style="color: #e9b2e3;">zmq</span>::str_buffer(<span style="color: #e9b96e;">"X-color:purple"</span>);
<span style="color: #b4fa70;">auto</span> <span style="color: #fcaf3e;">res</span> = sock.recv(msg, <span style="color: #e9b2e3;">zmq</span>::<span style="color: #e9b2e3;">recv_flags</span>::none);
<span style="color: #e9b2e3;">std</span>::<span style="color: #8cc4ff;">string</span> <span style="color: #fcaf3e;">val</span> = msg.gets(<span style="color: #e9b96e;">"X-color"</span>);
assert(val == <span style="color: #e9b96e;">"purple"</span>);
</pre>
</div>
</div>
</div>
<div id="outline-container-orga25afc6" class="outline-3">
<h3 id="orga25afc6">Socket references</h3>
<div class="outline-text-3" id="text-orga25afc6">
<p>
Sockets in <b>cppzmq</b> can not be copied (they can be moved) while it is usual that we want various parts of our application code to share access to the same socket. We can pass around an lvalue reference to our socket but that is not always possible or convenient.
</p>
<p>
To help with this, we are given a <code>zmq::socket_ref</code> which refers to but does not own a socket. With a socket ref our code can do almost everything it would do with a full socket object and it can know if the underlying socket has been closed.
</p>
<div class="org-src-container">
<pre class="src src-c++"><span style="color: #e9b2e3;">zmq</span>::<span style="color: #8cc4ff;">socket_t</span> <span style="color: #fce94f;">sock</span>(ctx, <span style="color: #e9b2e3;">zmq</span>::<span style="color: #e9b2e3;">socket_type</span>::pub);
<span style="color: #e9b2e3;">zmq</span>::<span style="color: #8cc4ff;">socket_ref</span> <span style="color: #fcaf3e;">sref</span> = sock;
<span style="color: #73d216;">// </span><span style="color: #73d216;">pass ref by value (copy)</span>
do_some_socket_stuff(sref);
<span style="color: #73d216;">// </span><span style="color: #73d216;">Check if our socket is still there</span>
<span style="color: #b4fa70;">if</span> (sref == <span style="color: #e9b2e3;">nullptr</span>) {
respond_to_closure();
}
<span style="color: #73d216;">// </span><span style="color: #73d216;">Do stuff with collections of socket refs</span>