Boost.Asio, 0MQ, and Windows
I have been following the excellent advice on using 0MQ and Boost.Asio on a POSIX-ish platform (MacOS) at http://preview.tinyurl.com/jw4krek. Unfortunately, though, I am writing code which needs to work on both POSIX-ish and Windows. I'm not having much luck, so far, with my attempts to translate this advice to the Windows side. I can't seem to figure out how to match the type returned by getsockopt(ZMQ_FD) on Windows and what I think should be the Windows equivalents of boost::asio::posix::stream_descriptor. Here is what I've tried: zmq::context_t zenv(1); zmq::socket_t zocket(zenv, ZMQ_PUSH); SOCKET zfd; std::size_t zfd_size = sizeof(zfd); zocket.getsockopt(ZMQ_FD, &zfd, &zfd_size); boost::asio::io_service ios; boost::asio::windows::stream_handle io(ios, zfd); And the error I get when I try to compile it. 2>Z:\zee-zmq-socket.cpp(14): error C2664: \ 'boost::asio::windows::basic_stream_handle<>::basic_stream_handle(\ boost::asio::io_service &,void *const &)' : cannot convert parameter \ 2 from 'SOCKET' to 'void *const &' 2> Reason: cannot convert from 'SOCKET' to 'void *const ' 2> Conversion from integral type to pointer type requires \ reinterpret_cast, C-style cast or function-style cast So far, my Google-fu has been weak; I can only seem to find examples which deal with Boost.Asio and 0MQ on POSIX-ish. I'm not sure what I need to do to correctly get from a SOCKET to a `void * const`. The closest advice that I've been able to find is about combining 0MQ and libcurl: http://preview.tinyurl.com/lbffx64. And this advice also makes me nervous that my compilation problems are only the tip of a much nastier iceberg hiding under the surface. In particular,
The reason why there is a assign, but no release-function for boost::asio::ip::tcp::sockets is that once a socket is "bound" to a completion port you cannot "unbound" it or "bound" it to another completion-port.
And so I'm worried there might be other gotchas about which I might not know and which would not even be so polite as to manifest themselves as compile-time errors. Thank you in advance for any help. ________________________________ This e-mail and any attachments are confidential. If it is not intended for you, please notify the sender, and please erase and ignore the contents.
On 08/09/2013 08:34 PM, Damien Kick wrote:
zocket.getsockopt(ZMQ_FD, &zfd, &zfd_size); boost::asio::io_service ios; boost::asio::windows::stream_handle io(ios, zfd);
And the error I get when I try to compile it.
2>Z:\zee-zmq-socket.cpp(14): error C2664: \ 'boost::asio::windows::basic_stream_handle<>::basic_stream_handle(\ boost::asio::io_service &,void *const &)' : cannot convert parameter \ 2 from 'SOCKET' to 'void *const &' 2> Reason: cannot convert from 'SOCKET' to 'void *const ' 2> Conversion from integral type to pointer type requires \ reinterpret_cast, C-style cast or function-style cast
Boost.Asio uses native_handle_type, which is a wrapper class for the underlying socket type. In the case of Windows this is SOCKET. However, you probably need to go via a intermediary variable: boost::asio::windows::stream_handle::native_handle_type handle(zfd); boost::asio::windows::stream_handle io(ios, handle); Disclaimer: I have not compiled it. You may need to include something from detail to make it work, or it may not work at all ;-)
And so I'm worried there might be other gotchas about which I might not know and which would not even be so polite as to manifest themselves as compile-time errors. Thank you in advance for any help.
Make sure to use null_buffers: http://www.boost.org/doc/html/boost_asio/overview/core/reactor.html
On Aug 10, 2013, at 5:51 AM, Bjorn Reese
On 08/09/2013 08:34 PM, Damien Kick wrote:
The reason why there is a assign, but no release-function for boost::asio::ip::tcp::sockets is that once a socket is "bound" to a completion port you cannot "unbound" it or "bound" it to another completion-port.
I nearly forgot this one. You have to make sure that the Boost.Asio socket does not close the underlying socket. Here is an explanation of how it can be done: http://lists.zeromq.org/pipermail/zeromq-dev/2011-May/011666.html I used to use this technique in an Asio wrapper for ZeroMQ and it works just fine. However, I got dissatisfied by how ZeroMQ hides too much detail from me (like disconnect, so I cannot do things like Wake-on-LAN.) So I ended up writing a (partial) implementation of the ZMTP/2.0 protocol directly with Asio: http://axiomq.sourceforge.net/
On Aug 11, 2013, at 5:12 AM, Bjorn Reese
msvcr100d.dll!_nh_malloc_dbg_impl(unsigned int nSize=8, int nhFlag=0, int nBlockUse=1, const char * szFileName=0x00000000, int nLine=0, int * errno_tmp=0x00c1fb0c) Line 239 + 0x19 bytes C++ msvcr100d.dll!_nh_malloc_dbg(unsigned int nSize=8, int nhFlag=0, int nBlockUse=1, const char * szFileName=0x00000000, int nLine=0) Line 302 + 0x1d bytes C++ msvcr100d.dll!malloc(unsigned int nSize=12712804) Line 56 + 0x15 bytes C++ 00c1fb64() 00cc8220()
However, I got dissatisfied by how ZeroMQ hides too much detail from me (like disconnect, so I cannot do things like Wake-on-LAN.) Yeah, I'd been thinking something similar, i.e. wanting to be able to know more about dis/connect, but then I discovered zmq_socket_monitor http://api.zeromq.org/3-2:zmq-socket-monitor. Maybe this was added since last you looked at it(0MQ)? ________________________________ This e-mail and any attachments are confidential. If it is not intended for you, please notify the sender, and please erase and ignore the contents.
On 08/11/2013 11:32 PM, Damien Kick wrote:
However, I got dissatisfied by how ZeroMQ hides too much detail from me (like disconnect, so I cannot do things like Wake-on-LAN.)
Yeah, I'd been thinking something similar, i.e. wanting to be able to know more about dis/connect, but then I discovered zmq_socket_monitor http://api.zeromq.org/3-2:zmq-socket-monitor. Maybe this was added since last you looked at it(0MQ)?
Yes, I am aware of zmq_socket_monitor [1]. You can use zmq_socket_monitor, but only to a limited degree. It was primarily designed for logging purposes, and it is difficult to make a decent connection management on top of it. The problem is that libzmq has its own connection management that handles things like re-connect and re-send. The event you get from zmq_socket_monitor is delivered via a queue (a ZMQ_PAIR socket), so you will always receive it after the fact. If you try to build your own connection management on top of it, it will compete with the libzmq handling. [1] http://lists.zeromq.org/pipermail/zeromq-dev/2012-August/018012.html
participants (2)
-
Bjorn Reese
-
Damien Kick