summaryrefslogtreecommitdiff
path: root/vim/bundle/slimv/swank-clojure/swank/util/net/sockets.clj
blob: 1c45ff10e9a163cdbd5efb8f6c69647346e57ed1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
(ns swank.util.net.sockets
  (:use (swank util)
        (swank.util.concurrent thread))
  (:import (java.net ServerSocket Socket SocketException InetAddress)))

(defn make-server-socket
  "Create a java.net.ServerSocket. A map of `options':

    :port - The port which this ServerSocket will listen on. It must
       be a number between 0-65535. If 0 or not provided, the server
       will be created on any free port.

    :host - The address the server will bind to, can be used on multi
      homed hosts. This can be an InetAddress or a hostname string. If
      not provided or nil, it will listen on all addresses.

    :backlog - The maximum queue length of incoming connection
      indications (ie. connection requests). If the queue is full, new
      indications will be refused. If set to less than or equal to 0,
      the default value will be used."
  ([] (ServerSocket.))
  ([options] (ServerSocket. (options :port 0)
                            (options :backlog 0)
                            (when-let [host (options :host)]
                              (if (instance? InetAddress host)
                                host
                                (InetAddress/getByName host))))))

(defn start-server-socket!
  "Given a `server-socket' (java.net.ServerSocket), call
   `handle-socket' for each new connection and provide current
   socket.

   This will return immediately with the Thread that is blocking for
   new connections. Use Thread.join() if you need to wait for the
   server to close."
  ([server-socket handle-socket]
     (dothread-keeping-clj nil
       (thread-set-name (str "Socket Server [" (thread-id) "]"))
       (with-open [#^ServerSocket server server-socket]
         (while (not (.isClosed server))
           (handle-socket (.accept server)))))))

(defn close-socket!
  "Cleanly shutdown and close a java.net.Socket. This will not affect
   an already running instance of SocketServer."
  ([#^Socket socket]
     (doto socket
       (.shutdownInput)
       (.shutdownOutput)
       (.close))))

(defn close-server-socket!
  "Shutdown a java.net.SocketServer. Existing connections will
  persist."
  ([#^ServerSocket server]
     (.close server)))