分散関数呼び出し
Posted feedbacks - Common Lisp
とりあえず検索して使えそうなコードを探しそれを参考にして切った貼ったで 作りました。 socket自体良く分かっていないため怪しいものができていると思います^^; できるだけ、処理系非依存にしたかったのですが、サーバ側は、SBCLの、 sb-bsd-socketに依存しているので、残念ながらsbclでしか動きません。 色々探している中で、usocketというものが使えそうだったので、クライアン ト側は、usocketを使用して作成しました。こちらは、USOCKETがサポートして いる処理系なら大丈夫だと思います。 USOCKETはASDF-INSTALL可能です。 サーバ: Pentium 1GHz Mem 768MB クライアント: iBook G4 800MHz Mem 640MB 通信経路: 100Mbps Ethernet 言語: SBCL 1.0.9 (サーバ/クライアント共に) 参考(サーバ) http://paste.lisp.org/display/1376 測定コード: (time (dotimes (i 10000) (get-pricestring (random 30000) (random 105) "server" 2000)) 10,000回実行にかかった時間 ------------------- real: 1202秒 user: 26秒 sys: 11秒 同一マシン(サーバ上)で実行 ------------------- real: 66秒 user: 27秒 sys: 10秒
see: Lisp Paste #1376
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | ;; ================================================================
;; クライアント
(defpackage doukaku-45 (:use :cl :usocket))
(in-package :doukaku-45)
(defun get-pricestring (price discount% server port)
(with-client-socket (socket stream server port)
(format stream "(~D ~D)~%" price discount%)
(force-output stream)
(read-line stream)))
;; ================================================================
;; サーバ
;; (ファイルにセーブして、$ sbcl --load server.lisp のように実行し起動させます。
(require :sb-bsd-sockets)
(use-package :sb-bsd-sockets)
(defun return-discount-price (stream price discount%)
(let ((discount-price (round (* price (/ (- 100 discount%) 100)))))
(format stream "販売価格 ~:D円(定価~:D円から~D%引き)"
discount-price price discount%)))
(defun valid-input-p (input)
(and (consp input)
(= 2 (length input))
(every #'numberp input)
(every (lambda (x) (<= 0 x)) input)
(<= 0 (cadr input) 100)))
(defun get-server-socket (hostname port)
(let ((socket (make-instance 'inet-socket :type :stream :protocol :tcp)))
(setf (sockopt-reuse-address socket) t)
(socket-bind socket
(host-ent-address (get-host-by-name hostname))
port)
(socket-listen socket 10)
socket))
(defun get-client-socket (server-socket)
(socket-accept server-socket))
(defun get-socket-stream (socket)
(socket-make-stream socket :input t :output t))
(defun close-socket (socket)
(socket-close socket))
(defun doukaku-45-server (port)
(let ((socket (get-server-socket "doritos" port)))
(handler-case
(progn
(format t "listening on ~D~%" port)
(do* ((client (get-client-socket socket) (get-client-socket socket))
(stream (get-socket-stream client) (get-socket-stream client)))
(())
(let ((in (read-from-string (read-line stream))))
(if (valid-input-p in)
(let ((mesg (apply #'return-discount-price nil in)))
(print mesg) (terpri) ;サーバ側確認用
(princ mesg stream))
(let ((mesg (format nil "~Sは不正な入力形式です。(価格 値引き率(0〜100%))" in)))
(print mesg) (terpri) ;サーバ側確認用
(princ mesg stream)))
(close-socket client))))
(condition (c) (format t "error occured: ~A~%" c)) )
(close-socket socket) ))
;; 2000番ポートでサーバ起動
(doukaku-45-server 2000)
|


沢渡 みかげ
#3401()
Rating0/0=0.00
[ reply ]