title: Pyro4 Tutorial, Error on different machines: not enough data
body: <p>I started to use Pyro4 from yesterday, so I'm experimenting the tutorial code from the official document. Everything ran perfectly locally, but I encountered problems when I adapt these examples in different machines, specifically, the stockmarket example. So here is my adapted code on server and client.<br>
  ==== Server Side ====<br>
  stockmarket.py<br></p>
  
  <pre><code>from __future__ import print_function
  import random
  import threading
  import time
  import Pyro4
  
  class StockMarket(object):
      def __init__(self, marketname, symbols):
          self.name = marketname
          self.symbolmeans = {}
          for symbol in symbols:
              self.symbolmeans[symbol] = random.uniform(20, 200)
          self.aggregators = []
  
      def generate(self):
          quotes = {}
          for symbol, mean in self.symbolmeans.items():
              if random.random() &lt; 0.2:
                  quotes[symbol] = round(random.normalvariate(mean, 20), 2)
          print("new quotes generated for", self.name)
          for aggregator in self.aggregators:
              aggregator.quotes(self.name, quotes)
  
      def listener(self,aggregator):
          print("market {0} adding new aggregator".format(self.name))
          self.aggregators.append(aggregator)
  
      def symbols(self):
          return list(self.symbolmeans.keys())
  
      def run(self):
          def generate_symbols():
              while True:
                  time.sleep(random.random())
                  self.generate()
          thread = threading.Thread(target=generate_symbols)
          thread.setDaemon(True)
          thread.start()
  
  def main():
      nasdaq = StockMarket("NASDAQ", ["AAPL", "CSCO", "MSFT", "GOOG"])
      newyork = StockMarket("NYSE", ["IBM", "HPQ", "BP"])
  
      daemon = Pyro4.Daemon("159.8.183.94")
      nasdaq_uri = daemon.register(nasdaq, "nasdaq")
      newyork_uri = daemon.register(newyork, "newyork")
      ns = Pyro4.locateNS()
      ns.register("example.stockmarket.nasdaq", nasdaq_uri)
      ns.register("example.stockmarket.newyork", newyork_uri)
      nasdaq.run()
      newyork.run()
      print("Stockmarkets running.")
      daemon.requestLoop()
  
  if __name__ == "__main__":
      main()
  </code></pre>
  
  <p>aggregator.py<br></p>
  
  <pre><code>from __future__ import print_function
  import Pyro4
  
  class Aggregator(object):
      def __init__(self):
          self.viewers = {}
          self.symbols = []
      def add_symbols(self, symbols):
          self.symbols.extend(symbols)
  
      def available_symbols(self):
          return self.symbols
  
      def view(self, viewer, symbols):
          print("aggregator gets a new viewer, for symbols:", symbols)
          self.viewers[viewer] = symbols
  
      def quotes(self, market, stockquotes):
          print (market)
          print (stockquotes)
          for symbol, value in stockquotes.items():
              for viewer, symbols in self.viewers.items():
                  if symbol in symbols:
                      viewer.quote(market, symbol, value)
  
  
  def main():
      aggregator = Aggregator()
      daemon = Pyro4.Daemon(host="159.8.183.94")
      agg_uri = daemon.register(aggregator, "aggregator")
      ns = Pyro4.locateNS()
      ns.register("example.stockquote.aggregator", agg_uri)
      for market, market_uri in ns.list(prefix="example.stockmarket.").items():
          print("joining market", market)
          stockmarket = Pyro4.Proxy(market_uri)
          stockmarket.listener(aggregator)
          aggregator.add_symbols(stockmarket.symbols())
      if not aggregator.available_symbols():
          raise ValueError("no symbols found! (have you started the stock market first?)")
      print("Aggregator running. Symbols:", aggregator.available_symbols())
      daemon.requestLoop()
  
  if __name__ == "__main__":
      main()
  </code></pre>
  
  <p>==== Client Side ====<br>
  viewer.py</p>
  
  <pre><code>from __future__ import print_function
  import sys
  import Pyro4
  
  if sys.version_info &lt; (3,0):
      input = raw_input
  
  
  class Viewer(object):
      def quote(self, market, symbol, value):
          print("{0}.{1}: {2}".format(market, symbol, value))
  
  
  def main():
      viewer = Viewer()
      daemon = Pyro4.Daemon()
      daemon.register(viewer)
      ns = Pyro4.locateNS(host="159.8.183.94", port=8080)
      aggregator_uri = ns.lookup("example.stockquote.aggregator")
      print ("aggregator uri is ", aggregator_uri)
      aggregator = Pyro4.Proxy(aggregator_uri)
      print("Available stock symbols:", aggregator.available_symbols())
      symbols = input("Enter symbols you want to view (comma separated):")
      symbols = [symbol.strip() for symbol in symbols.split(",")]
      aggregator.view(viewer, symbols)
      print("Viewer listening on symbols", symbols)
      daemon.requestLoop()
  
  if __name__ == "__main__":
      main()
  </code></pre>
  
  <p>==== How I run the code ====<br>
  On server machine, I ran the following code to define name server</p>
  
  <pre><code>python -m Pyro4.naming --host 159.8.183.94 --port 8080
  </code></pre>
  
  <p>Then I ran stockmarket.py and aggregator.py, everything is fine so far. Afer that, I started viewer.py, type the symbols I want to see, then I observe an error from stockmarket.py<br></p>
  
  <pre><code>Exception in thread Thread-18:
  Traceback (most recent call last):
    File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
      self.run()
    File "/usr/lib/python2.7/threading.py", line 763, in run
      self.__target(*self.__args, **self.__kwargs)
    File "stockmarket.py", line 37, in generate_symbols
      self.generate()
    File "stockmarket.py", line 24, in generate
      aggregator.quotes(self.name, quotes)
    File "/usr/local/lib/python2.7/dist-packages/Pyro4/core.py", line 171, in __call__
      return self.__send(self.__name, args, kwargs)
    File "/usr/local/lib/python2.7/dist-packages/Pyro4/core.py", line 410, in _pyroInvoke
      msg = message.Message.recv(self._pyroConnection, [message.MSG_RESULT], hmac_key=self._pyroHmacKey)
    File "/usr/local/lib/python2.7/dist-packages/Pyro4/message.py", line 168, in recv
      msg = cls.from_header(connection.recv(cls.header_size))
    File "/usr/local/lib/python2.7/dist-packages/Pyro4/socketutil.py", line 448, in recv
      return receiveData(self.sock, size)
    File "/usr/local/lib/python2.7/dist-packages/Pyro4/socketutil.py", line 182, in receiveData
      raise err
  ConnectionClosedError: receiving: not enough data
  </code></pre>
  
  <p>I think it's only a small bug in my code, and I've been stuck here for several hours, any suggestions or help will be very appreciated!! Thanks!!</p>