Shammer's Philosophy

My private adversaria

CLISP で server-socket に with-open-stream を使うと・・・

CLISP echo-server & echo-client - Shammerismの補足情報。
サーバーに対しても、with-open-stream を使用したいと思ったが、使用した場合は
停止の際に毎回以下のエラーが出てしまう。

*** - NO-APPLICABLE-METHOD: When calling #<STANDARD-GENERIC-FUNCTION CLOSE> with arguments (#<SOCKET-SERVER 0.0.0.0:7001>), no method is applicable.

内容としては、close を試行したけれども対象がない、というように見える。
いろいろやったがどうもこれを回避することができず、結局 server-socket は単純に let で指定することでうまくいった。
以下のように書いた際にうまくいくのが一番しっくり来るのだがそうはならなかった。

  (with-open-stream ((server (socket:socket-server 7001)))
    (format t "~&Waiting for a connection on ~S:~D~%"
	    (socket:socket-server-host server)
	    (socket:socket-server-port server))
    ;; Infinite loop, terminated if received "quit" message from client.
    (let ((running-flag "running"))
      (do ()
	  ((string-equal running-flag "quit"))
	(with-open-stream (client (socket:socket-accept server))
	  (multiple-value-bind (local-host local-port) (socket:socket-stream-local client)
	    (multiple-value-bind (remote-host remote-port) (socket:socket-stream-peer client)
	      (format t "~&Connection: ~S:~D -- ~S:~D~%"
		      remote-host remote-port local-host local-port)))
	  ;; loop is terminated when the remote host closes the connection or on EXT:EXIT
	  (loop
	     (when (eq :eof (socket:socket-status (cons client :input)))
	       (return))
	     (let ((line (read-line client nil 'eof)))
	       (format t "~A~%" line)
	       (when (string-equal line "quit")
		 (setf running-flag "quit"))))))))

上記の with-open-stream を let にすれば、quit という文字を受信した直後は server-socket は TIME_WAIT になるので、この書き方が正しいのかも。