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
[email protected]<mailto:[email protected]>
Unsere Pflichtangaben gemäß § 35a GmbHG / §§ 161, 125a HGB finden Sie unter 
de.cgi.com/pflichtangaben<http://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: [email protected] [[email protected]]" 
im Auftrag von "KIU Shueng Chuan [[email protected]]
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 
<[email protected]<mailto:[email protected]>> 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<http://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
[email protected]<mailto:[email protected]>
Unsere Pflichtangaben gemäß § 35a GmbHG / §§ 161, 125a HGB finden Sie unter 
de.cgi.com/pflichtangaben<http://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: 
[email protected]<mailto:[email protected]> 
[mailto:[email protected]<mailto:[email protected]>]
 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" 
<[email protected]<mailto:[email protected]>> 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<http://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<http://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<http://127.0.0.1:5000>          0.0.0.0:*    
           LISTEN      32615/./stream_s
tcp        0      0 127.0.0.1:5000<http://127.0.0.1:5000>          
127.0.0.1:34270<http://127.0.0.1:34270>         ESTABLISHED 32615/./stream_s
tcp        0      0 127.0.0.1:34270<http://127.0.0.1:34270>         
127.0.0.1:5000<http://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
[email protected]<mailto:[email protected]>
http://lists.zeromq.org/mailman/listinfo/zeromq-dev

_______________________________________________
zeromq-dev mailing list
[email protected]<mailto:[email protected]>
http://lists.zeromq.org/mailman/listinfo/zeromq-dev


_______________________________________________
zeromq-dev mailing list
[email protected]
http://lists.zeromq.org/mailman/listinfo/zeromq-dev

Reply via email to