Shammer's Philosophy

My private adversaria

Socket server sample with string-output-stream returns response from text files

string-output-streamをサーバーで使ってみる - Shammerismを改良し、応答をファイルから読み出したデータで返すことにする。あらかじめ、x.txtという名前のファイルを用意しておく。

$ echo 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz > x.txt
$ cat x.txt
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
$

書き換えたサーバープログラムは以下。

(with-open-socket
    (server :type :stream
	    :connect :passive
	    :local-host "localhost"
	    :local-port 7080
	    :reuse-address t)
  (let ((client (accept-connection server)))
    (format t "> Server received a message: ~%")
    (do () ()
      (let ((c (read-byte client nil 'eof)))
	(when (or (equal c 10)
		  (eql c 'eof))
	  (return))
	(format t "~A " c)))
    (format t "~%> Received Complete...~%")
    (format t "Sending Response...~%")
    (let* ((s (make-string-output-stream))
	   (*standard-output* s))
      (with-open-file
	  (f "x.txt" :direction :input :if-does-not-exist :error)
	(do () ()
	  (let ((line (read-line f nil 'eof)))
	    (when (or (null line)
		      (eql line 'eof))
	      (return))
	    (format t "~A" line))))
      (format client (get-output-stream-string s)))
    (close client)))
(quit)

これを実行すると以下のようになる。前回と同じだ。

$ ccl64 -l tcp-passive-server.lisp 
> Server received a message: 
65 66 67 68 69 70 71 
> Received Complete...
Sending Response...
$

クライアントは、

$ nc 127.0.0.1 7080
ABCDEFG
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz$

となった。用意したファイルが改行で終わっているはずが最後改行されていない。read-lineでは改行を読み込まないのだろうか。ここはちょっと考えないといけないかも。
直接の書き出しはstring-output-streamをサーバーで使ってみる - Shammerismで問題ないことがわかっている。ファイルがテキストであれば、読み込んだ行をそのまま送ることはできそうというのもわかった。
次は別の関数で(format t "XXX")とした場合の挙動も念の為確認する。恐らく問題ないと思われるが。