Shammer's Philosophy

My private adversaria

string-output-streamをサーバーで使ってみる

format や prin1 で文字列を受け取る - Shammerismで、make-string-output-streamを使ったときの結果を書いたが、これを TCP の Server の中で使ってみたい。
受信した文字を標準出力に書き出すだけのサーバーは以下のようになるが、

(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 ((line (read-line client nil 'eof)
	       (read-line client nil 'eof)))
	((or (string-equal line (string '#\Return))
	     (eql line 'eof)))
      (dolist (i (coerce line 'list))
	(format t "~:c" i))
      (format t "~%"))
    (format t "> Received Complete...~%")
    (close client))))

これを書き換えて、応答データを format t で全て書き出し、その応答をstring-output-streamから読み込んで応答するように変更する。

(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))
      (format t "Hello, World!!!~%")
      (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
Hello, World!!!
$

Hello, World!!!は、

(format t "Hello, World!!!~%")

と実行しているが、サーバー側の標準出力でなく、クライアントに返されている。とりあえず、やろうとしていたことは確認できた。