[zeromq-dev] Empty message does not close ZMQ_STREAM socket?

Greg Young gregoryyoung1 at gmail.com
Mon Mar 21 17:13:02 CET 2016


The code I posted works both as a stand alone and an actor based
server (the close works as well). You should be able to come close to
just copy/pasting them to working code.

Note I do pass a valid array here: zmq_send (socket, 0, 0, 0);

Also I am not sure about
        /* NOTE: If we don't use ZMQ_SNDMORE, then we won't be able to
send more */

I am not a heavily experienced user of zmq but my code works fine with
multiple clients, it closes the one that it intended to, others still
work. I understood sendmore as being per connection but maybe im off.

Cheers,

Greg

On Mon, Mar 21, 2016 at 4:06 PM, Auer, Jens <jens.auer at cgi.com> wrote:
> Hi,
>
> I tried that before and thought that sending the close message repetitively
> would do the trick. To better see if the socket is really closed, I set the
> reconnect interval to ten minutes in the client by setting
>     int tenminutes = 60000;
>     client.setsockopt(ZMQ_RECONNECT_IVL, &tenminutes, sizeof(tenminutes));
>
> Now, when I use the following server which is basically taken from the
> manpage, I can close the socket by sending the close message twice. Removing
> the ZMQ_SNDMORE flag does not change anything.
>
> int main(int argc, char* argv[]) {
>         int n = std::atoi(argv[1]);
>     void *ctx = zmq_ctx_new ();
>     /* Create ZMQ_STREAM socket */
>     void *socket = zmq_socket (ctx, ZMQ_STREAM);
>
>     int rc = zmq_bind (socket, "tcp://127.0.0.1:5000");
>     /* Data structure to hold the ZMQ_STREAM ID */
>     uint8_t id [256];
>     size_t id_size = 256;
>     /* Data structure to hold the ZMQ_STREAM received data */
>     uint8_t raw [256];
>     size_t raw_size = 256;
>     for(int i=0; i != n; ++i)
>     {
>         /*  Get HTTP request; ID frame and then request */
>         id_size = zmq_recv (socket, id, 256, 0);
>         assert (id_size > 0);
>         std::cout << id_size << std::endl;
>         raw_size = zmq_recv (socket, raw, 256, 0);
>
>         /* Closes the connection by sending the ID frame followed by a zero
> response */
>         zmq_send (socket, id, id_size, ZMQ_SNDMORE);
>         zmq_send (socket, 0, 0, 0);
>         /* NOTE: If we don't use ZMQ_SNDMORE, then we won't be able to send
> more */
>         /* message to any client */
>     }
>     std::cout << "Done" << std::endl;
>     int i;
>     std::cin >> i;
>     zmq_close (socket); zmq_ctx_destroy (ctx);
>     return 0;
> }
>
> Cheers,
>   Jens
>
> --
> Jens Auer | CGI | Software-Engineer
> CGI (Germany) GmbH & Co. KG
> Rheinstraße 95 | 64295 Darmstadt | Germany
> T: +49 6151 36860 154
> jens.auer at cgi.com
> Unsere Pflichtangaben gemäß § 35a GmbHG / §§ 161, 125a HGB finden Sie unter
> de.cgi.com/pflichtangaben.
>
> CONFIDENTIALITY NOTICE: Proprietary/Confidential information belonging to
> CGI Group Inc. and its affiliates may be contained in this message. If you
> are not a recipient indicated or intended in this message (or responsible
> for delivery of this message to such person), or you think for any reason
> that this message may have been addressed to you in error, you may not use
> or copy or deliver this message to anyone else. In such case, you should
> destroy this message and are asked to notify the sender by reply e-mail.
> ________________________________
> Von: zeromq-dev-bounces at lists.zeromq.org
> [zeromq-dev-bounces at lists.zeromq.org]" im Auftrag von "KIU Shueng Chuan
> [nixchuan at gmail.com]
> Gesendet: Montag, 21. März 2016 15:38
> An: ZeroMQ development list
> Betreff: Re: [zeromq-dev] Empty message does not close ZMQ_STREAM socket?
>
> Hi Jens,
>
> I tried out the pair of programs in your original post. Indeed, I got the
> behavior that you described using ZeroMQ 4.1.2.
>
> Putting the server code into a while loop did the trick.
> ```c++
> server.bind(address);
> while (1)
> {
>    // recv connection
>    // send disconnection
> }
> int i;
> std::cin >> i;
>
> ```
>
> I think in my own code, I have only ever used it in this forever loop
> fashion. Hmm...
>
>
> On Mon, Mar 21, 2016 at 9:11 PM, Auer, Jens <jens.auer at cgi.com> wrote:
>>
>> Hi,
>>
>>
>>
>> Thanks for the suggestion. I have modified my example to copy the id into
>> a new message, but it did not change anything. I have also tried a second
>> version of the server side which is basically the example provided at the
>> bottom of the manual page:
>>
>> int main2(int argc, char* argv[]) {
>>
>>         int n = std::atoi(argv[1]);
>>
>>         void *ctx = zmq_ctx_new ();
>>
>>         /* Create ZMQ_STREAM socket */
>>
>>         void *socket = zmq_socket (ctx, ZMQ_STREAM);
>>
>>
>>
>>         int rc = zmq_bind (socket, "tcp://127.0.0.1:5000");
>>
>>         /* Data structure to hold the ZMQ_STREAM ID */
>>
>>         uint8_t id [256];
>>
>>         size_t id_size = 256;
>>
>>         /* Data structure to hold the ZMQ_STREAM received data */
>>
>>         uint8_t raw [256];
>>
>>         size_t raw_size = 256;
>>
>>         for(int i=0; i != n; ++i)
>>
>>         {
>>
>>                 /*  Get HTTP request; ID frame and then request */
>>
>>                 id_size = zmq_recv (socket, id, 256, 0);
>>
>>                 assert (id_size > 0);
>>
>>                 std::cout << id_size << std::endl;
>>
>>                 raw_size = zmq_recv (socket, raw, 256, 0);
>>
>>
>>
>>                 /* Closes the connection by sending the ID frame followed
>> by a zero response */
>>
>>                 zmq_send (socket, id, id_size, ZMQ_SNDMORE);
>>
>>                 zmq_send (socket, 0, 0, ZMQ_SNDMORE);
>>
>>                 /* NOTE: If we don't use ZMQ_SNDMORE, then we won't be
>> able to send more */
>>
>>                 /* message to any client */
>>
>>         }
>>
>>         std::cout << "Done" << std::endl;
>>
>>         int i;
>>
>>         std::cin >> i;
>>
>>         zmq_close (socket); zmq_ctx_destroy (ctx);
>>
>>         return 0;
>>
>> }
>>
>>
>>
>> This has the same problem as described before that the socket is not
>> closed and I even receive an empty message at the client’s side.
>>
>>
>>
>> Cheers,
>>
>>   Jens
>>
>>
>>
>> --
>>
>> Dr. Jens Auer | CGI | Software Engineer
>>
>> CGI Deutschland Ltd. & Co. KG
>> Rheinstraße 95 | 64295 Darmstadt | Germany
>>
>> T: +49 6151 36860 154
>>
>> jens.auer at cgi.com
>>
>> Unsere Pflichtangaben gemäß § 35a GmbHG / §§ 161, 125a HGB finden Sie
>> unter de.cgi.com/pflichtangaben.
>>
>>
>>
>> CONFIDENTIALITY NOTICE: Proprietary/Confidential information belonging to
>> CGI Group Inc. and its affiliates may be contained in this message. If you
>> are not a recipient indicated or intended in this message (or responsible
>> for delivery of this message to such person), or you think for any reason
>> that this message may have been addressed to you in error, you may not use
>> or copy or deliver this message to anyone else. In such case, you should
>> destroy this message and are asked to notify the sender by reply e-mail.
>>
>>
>>
>> From: zeromq-dev-bounces at lists.zeromq.org
>> [mailto:zeromq-dev-bounces at lists.zeromq.org] On Behalf Of KIU Shueng Chuan
>> Sent: 21 March 2016 11:43
>> To: ZeroMQ development list
>> Subject: Re: [zeromq-dev] Empty message does not close ZMQ_STREAM socket?
>>
>>
>>
>> There's something in the manpage that your code doesn't do.
>>
>> > To open a connection to a server, use the zmq_connect call, and then
>> > fetch the socket identity using the ZMQ_IDENTITY zmq_getsockopt call.
>>
>> I don't recall if this was strictly necessary but I see in my code that I
>> did fetch the identity but immediately discarded it.
>>
>> I have some python scripts here where the server code disconnects the
>> client.
>> https://github.com/pijyoi/test_zmqstream
>> See zmqstream_publisher.py and zmqstream_subscriber.py
>>
>> On 21 Mar 2016 5:07 pm, "Auer, Jens" <jens.auer at cgi.com> wrote:
>>
>> Hi,
>>
>> I am trying to close a TCP socket over a ZMQ_STREAM by sending an identity
>> frame followed by an empty message, as described in the manual ("To close a
>> specific connection, send the identity frame followed by a zero-length
>> message"). I have a simple client/server example:
>> #include <zmq.hpp>
>> #include <iostream>
>> #include <cstdlib>
>>
>> int main2() {
>>     std::string address = "tcp://127.0.0.1:5000";
>>
>>     zmq::context_t zmq;
>>     zmq::socket_t server(zmq, ZMQ_STREAM);
>>
>>     server.bind(address);
>>
>>     zmq::message_t id;
>>     zmq::message_t m;
>>     server.recv(&id);
>>     server.recv(&m);
>>     std::cout << "Connection received: " << id.size() << std::endl;
>>
>>     zmq::message_t empty{};
>>
>>     server.send(id, ZMQ_SNDMORE);
>>     server.send(empty, ZMQ_SNDMORE );
>>
>>     int i;
>>     std::cin >> i;
>>
>>     return 0;
>> }
>>
>> #include <zmq.hpp>
>> #include <iostream>
>>
>> int main() {
>>     std::string address = "tcp://127.0.0.1:5000";
>>
>>     zmq::context_t zmq;
>>     zmq::socket_t client(zmq, ZMQ_STREAM);
>>
>>     client.connect(address);
>>
>>     zmq::message_t m3;
>>     zmq::message_t m4;
>>     client.recv(&m3);
>>     client.recv(&m4);
>>
>>     std::cout << "Connection established" << std::endl;
>>
>>     {
>>         zmq::message_t m5;
>>         zmq::message_t m6;
>>         client.recv(&m5);
>>         client.recv(&m6);
>>     }
>>
>>     std::cout << "Connection closed" << std::endl;
>>     int i;
>>     std::cin >> i;
>>
>>     return 0;
>> }
>>
>> When I start the server and then the client, the server will receive the
>> connection message, but the empty message does not close the socket:
>> ./stream_s 2
>> Connection received: 5
>> /tmp/stream_c
>> Connection established
>>
>> tcp        0      0 127.0.0.1:5000          0.0.0.0:*               LISTEN
>> 32615/./stream_s
>> tcp        0      0 127.0.0.1:5000          127.0.0.1:34270
>> ESTABLISHED 32615/./stream_s
>> tcp        0      0 127.0.0.1:34270         127.0.0.1:5000
>> ESTABLISHED 32618/stream_c
>>
>> I have also created a second example where the server sends the close
>> message twice. Here, the client actually receives the close message as an
>> empty message. Why is this even possible over a ZMQ_STREAM socket?
>>
>> I am using ZeroMQ 4.1.4, so the notification messages should be enabled by
>> default without setting ZMQ_STREAM_NOTIFY, and I have also tested 4.1.2 to
>> check for a regression.
>>
>> Best wishes,
>>   Jens
>>
>>
>> _______________________________________________
>> zeromq-dev mailing list
>> zeromq-dev at lists.zeromq.org
>> http://lists.zeromq.org/mailman/listinfo/zeromq-dev
>>
>>
>> _______________________________________________
>> zeromq-dev mailing list
>> zeromq-dev at lists.zeromq.org
>> http://lists.zeromq.org/mailman/listinfo/zeromq-dev
>>
>
>
> _______________________________________________
> zeromq-dev mailing list
> zeromq-dev at lists.zeromq.org
> http://lists.zeromq.org/mailman/listinfo/zeromq-dev
>



-- 
Studying for the Turing test



More information about the zeromq-dev mailing list