An example client code to binary-communicate with a TCP server.
TCP サーバとバイナリ通信するクライアントコードの例です.
Give informations of a TCP server to the first argument as a map.
:host
is a string representing an IP address or a hostname which can be forward-looked up and :port
is an integer represents a port.
Give a sequence of integers from 0 upto 255 representing a command to be sent to a server as the 2nd argument cmd
.
The 3rd len
is an expected number of bytes of a response from a server as an integer.
Specifiy the time to timeout in milli second as an integer.
Though my code uses clojure.tools.logging,
you can remove :require
clause and replace warn
, debug
and trace
to println
instead
or just comment them out.
最初の引数にマップで TCP サーバの情報を指定します.
:host
にホストの IP アドレスまたは正引き可能なホスト名を文字列で :port
にポート番号を整数で渡します.
二番目の引数 cmd
には, サーバに送りたいコマンドのバイト列を 0~255 の整数のシーケンスとして渡します.
三番目の引数 len
に想定されるサーバからのレスポンスのバイト数を整数で指定します.
四番目の引数 timeout
にタイムアウトするまでのミリ秒単位の待ち時間を整数で指定します.
例のコードでは
clojure.tools.logging
を使います.
:require
節を消して, warn
, debug
, trace
を println
で置き換えたりコメントアウトしても良いです.
Only the sequence to read bytes is explained below. About other parts, code will explain itself enough.
読み込み手順のみ下に説明します. 他の部分はコードを読めばだいたい分かるでしょう.
; m: number of bytes already read
; t: number of times tried to read
; initialize both to 0
(loop [m 0 t 0]
; 1. If number of bytes already read is
; smaller than expected number and
; number of times is smaller than
; timeout [ms] divided 10 [ms],
; go to 2,
; else go to 3
(if (and (< m len) (< t u))
; 2. If the input stream has one or more bytes,
(let [l (if (.available is)
; read them,
(.read is ibuf m (- len m))
; else wait 10 [ms]
(do (Thread/sleep 10) 0))]
; update m and t and back to 1.
(recur (+ m (long l)) (inc t)))
; 3. return number of bytes read
m))
; m: 既に読み込んだバイト数
; t: 読み込みを試した回数
; をそれぞれ 0 に初期化します.
(loop [m 0 t 0]
; 1. 読み込んだバイト数が期待するより小さく
; 且つ, 読み込みを試した回数が, 指定され
; たタイムアウト[ミリ秒] を 10 で割った
; ものよりも小さいならば 2
; そうでなければ 3
(if (and (< m len) (< t u))
; 2. 入力ストリームに入力があれば
(let [l (if (.available is)
; それを読み込み
(.read is ibuf m (- len m))
; そうでなければ 10ミリ秒待って
(do (Thread/sleep 10) 0))]
; m と t を更新して 1. へ戻ります.
(recur (+ m (long l)) (inc t)))
; 3. 読み込んだバイト数を返します.
m))