[zeromq-dev] IPC on Windows (again)
mato at kotelna.sk
Fri Mar 18 14:09:42 CET 2011
marcelo.cantos at gmail.com said:
> I've been mulling over the Windows ipc problem and it occurred to me that
> Erlang solves a very similar problem (allowing nodes to talk to each other)
> essentially using option 4 with a helper program, called epmd (Erlang Port
> Mapper Daemon). epmd accepts requests to associate a name with a port, and
> allocates a port for that name on the fly, or returns the previously allocated
> port on subsequent requests using the same name.
> In ZeroMQ, this might work by having a process (zpmd?) is responsible for
> binding to dynamic port numbers for use by the ipc transport, and which hands
> the port over to the server process — when it turns up — via a call to
> WSADuplicateSocket(). Any ZMQ process trying to use ipc will first check to see
> that zpmd is running; if it isn't, the ZMQ library will fire it up before
> trying to communicate with it. Zpmd and the ZMQ library would communicate
> either via a known port or a named pipe.
> This is a bit of a hack, but it seems to me that it should be a fairly robust
> hack, and is surely better than not supporting ipc on Windows at all. The only
> thing I'm not sure about is whether calling bind() long before the real server
> turns up will break clients connecting to the bound port.
> The thing I particularly like about this solution is that it doesn't intrude
> into the ZMQ library. I can go off and implement a proof-of-concept without
> spending huge amounts up time coming to grips with the core networking code,
> and all the time worrying that I am fundamentally breaking the inner workings
> of ZMQ. Even so, I thought I'd run this by the group as an informal proposal,
> to see if there's anything I've missed, before I burn too much time on it.
If I understand you correctly, what you're proposing is implementing ipc://
on Windows by emulating it using local TCP sockets, with an external
service providing the ipc://<name> to local TCP port mapping?
Given that one of the major points with 0MQ is that it is just a library
and no daemon/service is required (and thus no installation of said daemon,
management of whether or not it is up and running, etc. etc.) I don't
think going down that route is a particularly good idea.
However, I do have one idea that might be worth pursuing. It would require
some Win32-specific changes to the 0MQ core (specifically, adding an extra
thread per context to handle IPC name lookup for that context) but at first
glance this does seem doable.
The idea is to use Named Pipes for the IPC name lookup, and nothing else.
So, it'd work something like this:
Creating the IPC endpoint ipc://<name> on Win32:
1) Attempt to CreateNamedPipe() the named pipe \\.\pipe\<name>
2) If that fails, another process is already using <name> for IPC, so fail.
3) If it succeeds, register it with a "named pipe manager" thread for
calling 0MQ context. At the same time, allocate a normal TCP listening
socket on localhost for the actual communication.
Connecting to an IPC endpoint ipc://<name> on Win32:
4) Attempt to ConnectNamedPipe() the named pipe \\.\pipe\<name>
5) If that fails, the endpoint doesn't exist, so fail.
6) If it succeeds, read up to EOF from the named pipe, which will return
the TCP port number of the local listening socket. Disconnect from the
7) Proceed as if connecting via the TCP transport.
So, the sole function of the extra thread is to respond to connections on
named pipes and send the TCP port number of the socket over which actual
communication will be performed.
What do you think? This approach would provide the name lookup without the
need for any external service.
More information about the zeromq-dev