LispでSocket送受信その2
一方的にメッセージを送るだけのクライアントと、受けたメッセージを表示してそのまま終了するサーバをサンプルとして作った(2011/01/11の記事)が、それを一歩進めて、サーバーは受け取ったメッセージをクライアントに送り返してから終了し、クライアントはその受け取ったメッセージを表示して終了する、というように改良してみた。
サーバー側の実装は以下のような感じ。
(defun open-echo-server (port) (let ((server (make-socket :type :stream :connect :passive :local-host "localhost" :local-port port))) (let ((client-socket (accept-connection server))) (format t "> Server received a message: ~%") (loop (let ((char (read-char client-socket nil nil))) (if (eql (char-code char) '10) (return)) (format t "~a~%" char) (format client-socket "~a" char))) (force-output client-socket) (close client-socket)) (close server)))
クライアント側の実装は以下のような感じ。
(defun send-message (destination-host destination-port message) (let ((client (make-socket :address-family :internet :type :stream :connect :active :remote-host destination-host :remote-port destination-port))) (format client message) (format client "~%") (force-output client) (loop (let ((char (read-char client nil nil))) (if (null char) (return)) (format t "~a~%" char))) (close client)))
サーバ側は、クライアントからのデータは改行までなので、受け取った文字(データ)がASCIIの10であったら読み込みを終了するようにしてみた。逆に、クライアント側は、サーバからNILを受け取ってエラーになったので、読み込んだデータがNILかどうかのチェックを行っている。Javaと違って、InputStreamとOutputStreamは隠蔽されているんだな。Socketに対して、読み込むか書き込むかの違いになっているんだ。個人的にはこっちの方が好きだな。