(ns tcp-bin (:require [clojure.tools.logging :refer :all])) (defn- i2b [i] (byte (if (< i 128) i (- i 256)))) (defn- b2i [b] (let [i (int b)] (if (< i 0) (+ i 256) i))) (defn oi "Send `cmd` bytes to `port` of `host` and receive `len` bytes response from it with `timeout` [ms] timeout." [{:keys [host port]} cmd len timeout] (try (with-open [s (java.net.Socket. ^String host ^int port) ^java.io.OutputStream os (.getOutputStream s) ^java.io.InputStream is (.getInputStream s)] (let [^bytes obuf (byte-array (map i2b cmd)) _ (trace "tcp-bin:oi:send:" (seq obuf)) _ (.write os obuf 0 (count cmd)) _ (.flush os) ^bytes ibuf (byte-array len) u (quot timeout 10) n (loop [m 0 t 0] (if (and (< m len) (< t u)) (let [l (if (.available is) (.read is ibuf m (- len m)) (do (Thread/sleep 10) 0))] (recur (+ m (long l)) (inc t))) m)) ] (trace "tcp-bin:oi:recv: [" n "]" (seq ibuf)) (map b2i (take n (seq ibuf))))) (catch Throwable t (warn t) (debug t t))))