'\" t .\" Title: zframe .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.79.1 .\" Date: 03/03/2019 .\" Manual: CZMQ Manual .\" Source: CZMQ 4.2.0 .\" Language: English .\" .TH "ZFRAME" "3" "03/03/2019" "CZMQ 4\&.2\&.0" "CZMQ Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" zframe \- Class for working with single message frames .SH "SYNOPSIS" .sp .nf // This is a stable class, and may not change except for emergencies\&. It // is provided in stable builds\&. // This class has draft methods, which may change over time\&. They are not // in stable releases, by default\&. Use \-\-enable\-drafts to enable\&. #define ZFRAME_MORE 1 // #define ZFRAME_REUSE 2 // #define ZFRAME_DONTWAIT 4 // // Create a new frame\&. If size is not null, allocates the frame data // to the specified size\&. If additionally, data is not null, copies // size octets from the specified data into the frame body\&. CZMQ_EXPORT zframe_t * zframe_new (const void *data, size_t size); // Create an empty (zero\-sized) frame CZMQ_EXPORT zframe_t * zframe_new_empty (void); // Create a frame with a specified string content\&. CZMQ_EXPORT zframe_t * zframe_from (const char *string); // Receive frame from socket, returns zframe_t object or NULL if the recv // was interrupted\&. Does a blocking recv, if you want to not block then use // zpoller or zloop\&. CZMQ_EXPORT zframe_t * zframe_recv (void *source); // Destroy a frame CZMQ_EXPORT void zframe_destroy (zframe_t **self_p); // Send a frame to a socket, destroy frame after sending\&. // Return \-1 on error, 0 on success\&. CZMQ_EXPORT int zframe_send (zframe_t **self_p, void *dest, int flags); // Return number of bytes in frame data CZMQ_EXPORT size_t zframe_size (zframe_t *self); // Return address of frame data CZMQ_EXPORT byte * zframe_data (zframe_t *self); // Return meta data property for frame // The caller shall not modify or free the returned value, which shall be // owned by the message\&. CZMQ_EXPORT const char * zframe_meta (zframe_t *self, const char *property); // Create a new frame that duplicates an existing frame\&. If frame is null, // or memory was exhausted, returns null\&. // Caller owns return value and must destroy it when done\&. CZMQ_EXPORT zframe_t * zframe_dup (zframe_t *self); // Return frame data encoded as printable hex string, useful for 0MQ UUIDs\&. // Caller must free string when finished with it\&. // Caller owns return value and must destroy it when done\&. CZMQ_EXPORT char * zframe_strhex (zframe_t *self); // Return frame data copied into freshly allocated string // Caller must free string when finished with it\&. // Caller owns return value and must destroy it when done\&. CZMQ_EXPORT char * zframe_strdup (zframe_t *self); // Return TRUE if frame body is equal to string, excluding terminator CZMQ_EXPORT bool zframe_streq (zframe_t *self, const char *string); // Return frame MORE indicator (1 or 0), set when reading frame from socket // or by the zframe_set_more() method CZMQ_EXPORT int zframe_more (zframe_t *self); // Set frame MORE indicator (1 or 0)\&. Note this is NOT used when sending // frame to socket, you have to specify flag explicitly\&. CZMQ_EXPORT void zframe_set_more (zframe_t *self, int more); // Return TRUE if two frames have identical size and data // If either frame is NULL, equality is always false\&. CZMQ_EXPORT bool zframe_eq (zframe_t *self, zframe_t *other); // Set new contents for frame CZMQ_EXPORT void zframe_reset (zframe_t *self, const void *data, size_t size); // Send message to zsys log sink (may be stdout, or system facility as // configured by zsys_set_logstream)\&. Prefix shows before frame, if not null\&. CZMQ_EXPORT void zframe_print (zframe_t *self, const char *prefix); // Probe the supplied object, and report if it looks like a zframe_t\&. CZMQ_EXPORT bool zframe_is (void *self); // Self test of this class\&. CZMQ_EXPORT void zframe_test (bool verbose); #ifdef CZMQ_BUILD_DRAFT_API // Destroy an item typedef void (zframe_destructor_fn) ( void **hint); // *** Draft method, for development use, may change without warning *** // Create a new frame from memory\&. Take ownership of the memory and calling the destructor // on destroy\&. CZMQ_EXPORT zframe_t * zframe_frommem (void *data, size_t size, zframe_destructor_fn destructor, void *hint); // *** Draft method, for development use, may change without warning *** // Return frame routing ID, if the frame came from a ZMQ_SERVER socket\&. // Else returns zero\&. CZMQ_EXPORT uint32_t zframe_routing_id (zframe_t *self); // *** Draft method, for development use, may change without warning *** // Set routing ID on frame\&. This is used if/when the frame is sent to a // ZMQ_SERVER socket\&. CZMQ_EXPORT void zframe_set_routing_id (zframe_t *self, uint32_t routing_id); // *** Draft method, for development use, may change without warning *** // Return frame group of radio\-dish pattern\&. CZMQ_EXPORT const char * zframe_group (zframe_t *self); // *** Draft method, for development use, may change without warning *** // Set group on frame\&. This is used if/when the frame is sent to a // ZMQ_RADIO socket\&. // Return \-1 on error, 0 on success\&. CZMQ_EXPORT int zframe_set_group (zframe_t *self, const char *group); #endif // CZMQ_BUILD_DRAFT_API Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zframe\&.c\*(Aq\&. .fi .SH "DESCRIPTION" .sp The zframe class provides methods to send and receive single message frames across 0MQ sockets\&. A \fIframe\fR corresponds to one zmq_msg_t\&. When you read a frame from a socket, the zframe_more() method indicates if the frame is part of an unfinished multipart message\&. The zframe_send method normally destroys the frame, but with the ZFRAME_REUSE flag, you can send the same frame many times\&. Frames are binary, and this class has no special support for text data\&. .sp Please add \fI@discuss\fR section in \fI\&./\&.\&./src/zframe\&.c\fR\&. .SH "EXAMPLE" .PP \fBFrom zframe_test method\fR. .sp .if n \{\ .RS 4 .\} .nf // Create two PAIR sockets and connect over TCP zsock_t *output = zsock_new (ZMQ_PAIR); assert (output); int port = zsock_bind (output, "tcp://127\&.0\&.0\&.1:*"); assert (port != \-1); zsock_t *input = zsock_new (ZMQ_PAIR); assert (input); rc = zsock_connect (input, "tcp://127\&.0\&.0\&.1:%d", port); assert (rc != \-1); // Send five different frames, test ZFRAME_MORE int frame_nbr; for (frame_nbr = 0; frame_nbr < 5; frame_nbr++) { frame = zframe_new ("Hello", 5); assert (frame); rc = zframe_send (&frame, output, ZFRAME_MORE); assert (rc == 0); } // Send same frame five times, test ZFRAME_REUSE frame = zframe_new ("Hello", 5); assert (frame); for (frame_nbr = 0; frame_nbr < 5; frame_nbr++) { rc = zframe_send (&frame, output, ZFRAME_MORE + ZFRAME_REUSE); assert (rc == 0); } assert (frame); zframe_t *copy = zframe_dup (frame); assert (zframe_eq (frame, copy)); zframe_destroy (&frame); assert (!zframe_eq (frame, copy)); assert (zframe_size (copy) == 5); zframe_destroy (©); assert (!zframe_eq (frame, copy)); // Test zframe_new_empty frame = zframe_new_empty (); assert (frame); assert (zframe_size (frame) == 0); zframe_destroy (&frame); // Send END frame frame = zframe_new ("NOT", 3); assert (frame); zframe_reset (frame, "END", 3); char *string = zframe_strhex (frame); assert (streq (string, "454E44")); freen (string); string = zframe_strdup (frame); assert (streq (string, "END")); freen (string); rc = zframe_send (&frame, output, 0); assert (rc == 0); // Read and count until we receive END frame_nbr = 0; for (frame_nbr = 0;; frame_nbr++) { zframe_t *frame = zframe_recv (input); if (zframe_streq (frame, "END")) { zframe_destroy (&frame); break; } assert (zframe_more (frame)); zframe_set_more (frame, 0); assert (zframe_more (frame) == 0); zframe_destroy (&frame); } assert (frame_nbr == 10); #if (ZMQ_VERSION >= ZMQ_MAKE_VERSION (4, 1, 0)) // Test zframe_meta frame = zframe_new ("Hello", 5); assert (frame); rc = zframe_send (&frame, output, 0); assert (rc == 0); frame = zframe_recv (input); const char *meta = zframe_meta (frame, "Socket\-Type"); assert (meta != NULL); assert (streq (meta, "PAIR")); assert (zframe_meta (frame, "nonexistent") == NULL); zframe_destroy (&frame); #endif zsock_destroy (&input); zsock_destroy (&output); #if defined (ZMQ_SERVER) // Create server and client sockets and connect over inproc zsock_t *server = zsock_new_server ("inproc://zframe\-test\-routing"); assert (server); zsock_t *client = zsock_new_client ("inproc://zframe\-test\-routing"); assert (client); // Send request from client to server zframe_t *request = zframe_new ("Hello", 5); assert (request); rc = zframe_send (&request, client, 0); assert (rc == 0); assert (!request); // Read request and send reply request = zframe_recv (server); assert (request); assert (zframe_streq (request, "Hello")); assert (zframe_routing_id (request)); zframe_t *reply = zframe_new ("World", 5); assert (reply); zframe_set_routing_id (reply, zframe_routing_id (request)); rc = zframe_send (&reply, server, 0); assert (rc == 0); zframe_destroy (&request); // Read reply reply = zframe_recv (client); assert (zframe_streq (reply, "World")); assert (zframe_routing_id (reply) == 0); zframe_destroy (&reply); // Client and server disallow multipart frame = zframe_new ("Hello", 5); rc = zframe_send (&frame, client, ZFRAME_MORE); assert (rc == \-1); rc = zframe_send (&frame, server, ZFRAME_MORE); assert (rc == \-1); zframe_destroy (&frame); zsock_destroy (&client); zsock_destroy (&server); #endif #ifdef ZMQ_RADIO // Create radio and dish sockets and connect over inproc zsock_t *radio = zsock_new_radio ("inproc://zframe\-test\-radio"); assert (radio); zsock_t *dish = zsock_new_dish ("inproc://zframe\-test\-radio"); assert (dish); // Join the group rc = zsock_join (dish, "World"); assert (rc == 0); // Publish message from radio zframe_t *message = zframe_new ("Hello", 5); assert (message); rc = zframe_set_group (message, "World"); assert (rc == 0); rc = zframe_send (&message, radio, 0); assert (rc == 0); assert (!message); // Receive the message from dish message = zframe_recv (dish); assert (message); assert (zframe_streq (message, "Hello")); assert (strcmp("World", zframe_group (message)) == 0); zframe_destroy (&message); zsock_destroy (&dish); zsock_destroy (&radio); #else frame = zframe_new ("Hello", 5); rc = zframe_set_group (frame, "World"); assert(rc == \-1); assert(errno == ENOTSUP); zframe_destroy (&frame); #endif char str[] = "hello"; frame = zframe_frommem (str, 5, mem_destructor, str); assert (frame); zframe_destroy (&frame); // The destructor doesn\*(Aqt free the memory, only changing the strid, // so we can check if the destructor was invoked assert (streq (str, "world")); #if defined (__WINDOWS__) zsys_shutdown(); #endif .fi .if n \{\ .RE .\} .sp .SH "AUTHORS" .sp The czmq manual was written by the authors in the AUTHORS file\&. .SH "RESOURCES" .sp Main web site: \m[blue]\fB\%\fR\m[] .sp Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> .SH "COPYRIGHT" .sp Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. .SH "NOTES" .IP " 1." 4 zeromq-dev@lists.zeromq.org .RS 4 \%mailto:zeromq-dev@lists.zeromq.org .RE