Hi Jens, Because the client is using ZMQ_STREAM, when it gets disconnected it immediately reattempts a reconnect.
So the first empty message is for connect. Second empty message is for disconnect. And the 3rd empty message is for the reconnect. And so on. On 22 Mar 2016 12:07 am, "Auer, Jens" <jens.a...@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.a...@cgi.com* <jens.a...@cgi.com> > 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:* zeromq-dev-boun...@lists.zeromq.org [ > zeromq-dev-boun...@lists.zeromq.org]" im Auftrag von "KIU Shueng Chuan [ > nixch...@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.a...@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.a...@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-boun...@lists.zeromq.org [mailto: >> zeromq-dev-boun...@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.a...@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@lists.zeromq.org >> http://lists.zeromq.org/mailman/listinfo/zeromq-dev >> >> _______________________________________________ >> zeromq-dev mailing list >> zeromq-dev@lists.zeromq.org >> http://lists.zeromq.org/mailman/listinfo/zeromq-dev >> >> > > _______________________________________________ > zeromq-dev mailing list > zeromq-dev@lists.zeromq.org > http://lists.zeromq.org/mailman/listinfo/zeromq-dev > >
_______________________________________________ zeromq-dev mailing list zeromq-dev@lists.zeromq.org http://lists.zeromq.org/mailman/listinfo/zeromq-dev