                 (second (nth choices choice-ndx))
                 (recur current-name-endpoint-map))))))
       (finally
-        (.start
-          (Thread.
-            (fn []
-              (.removeServiceListener mdns-service reg-type service-listener)
-              (.close mdns-service))))))))
+        (.start (Thread. tear-down-mdns))))))
 
 (defn socket
   [host port]

                                    {:address (.getAddress info)
                                     :port    (.getPort info)})}]
                  (swap! name-endpoint-map merge entry))))))]
    (try
      (.addServiceListener mdns-service reg-type service-listener)
      (loop [count 0]
        (when (empty? @name-endpoint-map)
          (Thread/sleep 100)
          (when (= 20 count)
            (println "\nSearching for devices ..."))
          (recur (inc count))))
      (Thread/sleep 500)                                    ;; Sleep a little more to catch stragglers
      (loop [current-name-endpoint-map @name-endpoint-map]
        (println)

    (doseq [[choice-number [bonjour-name _]] (name-endpoint-map->choice-list name-endpoint-map)]
      (println (str "[" choice-number "] " (bonjour-name->display-name bonjour-name))))))

(defn setup-mdns
  "Sets up mDNS to populate atom supplied in name-endpoint-map with discoveries.
  Returns a function that will tear down mDNS."
  [reg-type name-endpoint-map]
  {:pre [(string? reg-type)]
   :post [(fn? %)]}
  (let [mdns-service (JmDNS/create)
        service-listener
        (reify ServiceListener
          (serviceAdded [_ service-event]
