接続されたストリームは、両方向通信チャンネルとして供給されるが、 接続確定処理は、入力・出力で別々である。 片方がサーバーとして参照され、もう一方がクライアントとして参照される。 サーバーとなった端(service access point)は、最初に確定される。 これは、make-socket-port関数により作成される。 この関数は、socket-portのインスタンスを返す。 ソケットポートのオブジェクトは、make-server-socket-streamによって 1つまたは複数のクライアントからの接続を受けるために使用される。 make-server-socket-streamへの呼び出しは、クライアントからの 接続要求が実際に起こるまで実行待ち状態となる。 クライアントは、ソケットアドレスを指定することによって make-client-socket-streamでソケットストリーム を複数作ることができる。
;;; an example of IPC through a socket stream: ;;; server side (setq saddr (make-socket-address :domain af_inet :host "etlic2" :port 2000)) (setq sport (make-socket-port saddr)) (setq sstream (make-server-socket-stream sport)) ;;; ;;; client side (setq caddr (make-socket-address :domain af_inet :host "etlic2" :port 2000)) (setq cstream (make-client-socket-stream caddr))
データベースや移動ロボットの環境シミュレータのようなアプリケーション では、1つのサーバーと複数のクライアント間の multiple connection service(多重接続サービス)が要求される。 この型のサーバーは、open-server関数によりプログラム することができる。 カレントホスト名と与えられたポート番号から open-serverは、接続要求にしたがってソケットポート(service access point) を作る。 このポートは非同期なので、 open-serverは遮断されず、直ちに返信する。 その後、接続要求はそれぞれEuslispのメインループを中断し、 ソケットストリーム が非同期に作成される。 このソケットストリームも非同期モードで働く。 open-serverの2番目の引き数にある非同期入力処理は、 新しいデータがこのストリームに現れたときはいつでも呼び出される。 30以上の接続が可能であるため、同時に多くのクライアントがサーバーの データにアクセスすることができる。
;; server side (defun server-func (s) (case (read s) ... ;do appropriate jobs according to inputs (open-server 3000 #'server-func) ... do other jobs in parallel ;; client-1 through client-N (setq s (connect-server "etlmmd" 3000)) (format s "..." ...) (finish-output s) ;issue a command to the server (read s) ;receive response
確実な通信チャンネルとして供給される接続指向 ストリームと対照的に 非接続 ソケットは、不確実な通信チャンネルである。 メッセージがなくなったり、重複したり、故障したりする可能性がある。 しかしながら、非接続 ソケットは、それぞれの接続にファイルディスクリプタを 割り当てる必要が無いし、 また、データやバッファのオーバーフローの読み込みをしないレシーバーでさえ 送信処理を中断することができないという利点がある。
非接続ソケットを作るためには、以下の命令を使用する。 メッセージはunix:sendtoとunix:recvfromによって変換される。
;;; receiver side (setq saddr (make-socket-address :domain af_inet :host "etlic2" :port 2001)) (setq sock (make-dgram-socket saddr)) (unix:recvfrom sock) ;;; ;;; client side (setq caddr (make-socket-address :domain af_inet :host "etlic2" :port 2001)) (setq sock (unix:socket (send caddr :domain) 2 0)) (unix:sendto sock caddr "this is a message") ;;; ;;; how to use echo service which is registered in /etc/services. (setq caddr (make-socket-address :domain af_inet :host "etlic2" :port (car (unix:getservbyname "echo")))) (setq echosock (unix:socket (send caddr :domain) 2 0)) (unix:sendto echosock caddr "this is a message") (unix:recvfrom echosock) --> "this is a messge"
make-socket-address &key :domain :pathname :host :port :proto :service [関数]
make-socket-port sockaddr [関数]
make-server-socket-stream sockport &optional (size 100) [関数]
make-client-socket-stream sockaddr &optional (size 100) [関数]
open-server port remote-func [関数]