Shammer's Philosophy

My private adversaria

SBCLで文字列をドット表記のIPアドレスに変換する

SBCLでSocketをオープンする時に使用するIPアドレスは、配列(vector)で表現する必要がある。具体的には以下のような感じにする。

(let ((server-socket (make-instance 'sb-bsd-sockets:inet-socket :type :stream :protocol :tcp)))
  (sb-bsd-sockets:socket-bind server #(0 0 0 0) 10080)
  ...

この書き方の場合、0.0.0.0 の 10080 ポートで listen する passive-socket になる。
どの言語でもそうだが、コマンドラインからの引数や何かのファイルから読み出されたデータは文字列として扱われることが多い。そのため、関数間での値の受け渡しは、渡す情報が多い場合は文字列の構造体として渡すことにし、少ない場合は文字列を想定することが多い。IPアドレスも文字列で渡して、socket-bind で使用できる感じに変換できるのが望ましい。これを実現できるのがmake-inet-address という関数。以下のように使用できる。

(sb-bsd-sockets:make-inet-address "127.0.0.1")

この結果は、#(127 0 0 1)になる。もちろん、socket-bind の引数として使用できる。IPアドレスに変換できない文字列を受け取った場合は、simple-error が throw される。

(handler-case
    (sb-bsd-sockets:make-inet-address "test")
  (error (e)
    (format t "~A was thrown.~%" (type-of e))))
SIMPLE-ERROR was thrown.
NIL

これをうまく利用することで listen-address を決定することができそうだ。