[zeromq-dev] Can't bind same ZMQ_UP/DOWNSTREAM multiple times.

Matt Weinstein matt_weinstein at yahoo.com
Tue Aug 17 14:02:17 CEST 2010


I thought this is what the :
	REQ =(*)= XREP==DEVICE==XREQ== REP

pattern is for.

Just have your clients connect() to the socket on the left half of the  
device (which is the left half of the device and is a bind().

On Aug 17, 2010, at 12:39 AM, Oliver Smith wrote:

>  On 8/16/2010 12:07 PM, Pieter Hintjens wrote:
>> Hi Oliver,
>>
>> I can repeat my previous reply.  After reading your email I still
>> don't understand why you need to bind to the same endpoint twice, and
>> why you expect this to work (it won't).
>>
>> You cannot bind two sockets to a single endpoint.  It's not a legal  
>> semantic.
>>
>> So what in fact is your question?  Sorry if I missed it.
> I did do a good job of making that a bit hidden.
>
> The question: What is the right pattern for doing this -- 1 -> N ->  
> M ->
> 1 four stage parallelism.
>
> Why it's even a question: Remember, "ZeroMQ sockets aren't /sockets/".
> That just happens to be one of the underlying mechanisms.
>
> From a networking perspective, I understand why multiple binds don't
> work. And setting SO_REUSEADDR would just be messy...
>
> But I would have thought that internally if multiple socket_ts tried  
> to
> bind to the same IP socket address ///via the same context/// you  
> would
> have handled that internally the same way that you handle multiple
> connects: thus allowing multiple threads within an application to
> service the same socket.
>
> Consider:
>
> 8x--- snip ---x8
> import zmq
> import re
>
> ctx = zmq.Context(8)
>
> class HTTPWorker(threading.Thread):
>     def __init__(self):
>         threading.Thread.__init__(self)
>         self.daemon = True
>         self.sock = ctx.socket(zmq.REP)
>         self.sock.bind("tcp://0.0.0.0:80")
>
>     def run(self):
>         urlMatch = re.compile(r'^GET\s+([/a-zA-Z0-9_.%-]+)')
>         while True:
>             msg = self.sock.recv()
>             matches = urlMatch.match(msg)
>             if matches and matches.group(1):
>                 content = readFile(matches.group(1))
>                 reply = headers(matches.group(1), content)
>                 self.sock.send(reply)
> 8x--- snip ---x8
>
> This would allow one processes to have multiple threads servicing a
> single TCP socket endpoint without the need to go through a device or
> have the operator fork multiple processors.
>
> I do absolutely understand why "self.sock.bind(same address multiple
> times)" on a single machine does not work. But that requires the
> end-user to be aware of the underlying network basis of the function  
> of
> "bind".
>
> Now consider:
>
>     # X threads are going to receive transparently
>     # multiplexed work from Q sources.
>     self.workin = ctx.socket(zmq.DOWNSTREAM)
>     self.workin.connect("inproc://stage1-worker")
>
>     # Those X stage1 workers are going to forward
>     # additional work to Y transparently
>     # multiplexed stage 2 workers.
>     self.workout = ctx.socket(zmq.UPSTREAM)
>     self.workout.bind("inproc://stage2-workers")
>
> Again -- I understand why, under the hood, BSD's bind(3) function
> returns address already in use.
>
> But I'm not using bind(3), I'm using zmq->context->bind. Therefore the
> answer to the question should be in ZeroMQ context terms and not
> sockets-api terms... If the answer was "because they are using  
> different
> contexts, and only one context can bind to a socket address" - that
> would work. But "only one endpoint can bind to a socket address even  
> on
> the same context as the other endpoint" doesn't... Certainly not in  
> many
> sample use cases.
>
> - Oliver
>
> _______________________________________________
> zeromq-dev mailing list
> zeromq-dev at lists.zeromq.org
> http://lists.zeromq.org/mailman/listinfo/zeromq-dev




More information about the zeromq-dev mailing list