AZ-Prolog ユーザーズマニュアル

## 9-7.ソケット

### 9-7-1.概要

ネットワーク通信プロトコル(TCP/IP)を利用したクライアントとサーバー間のネットワーク接続についてインターフェースを提供します。
以下に、インターフェースとして提供する述語と概要及びAZ-Prolog Version7でのプラットフォーム別サポート状況を示します。

| 述語インターフェース名 | 概要説明 | 通常(※1) | Windows | Linux/Mac
A | server_create/2 , server_create/3 | ソケットサーバーを生成します | ○ | ○ | ○
server_accept/3 | クライアントからの接続要求時に接続を確立します | ○ | ○ | ○
client_connect/3 | ソケット接続の接続要求を行います | ○ | ○ | ○
client_connect_async/3 | ソケット接続の接続要求を非同期で行います | ○ | × | ○
socket_send/2 | ソケットにデータを送信します | ○ | ○ | ○
socket_send_list/2 | ソケットにリストを送信します | ○ | ○ | ○
socket_receive/2 | ソケットからデータを受信します | ○ | ○ | ○
socket_receive_list/2 | ソケットからリストを受信します | ○ | ○ | ○
socket_close/1 | ソケット接続を終了します | ○ | ○ | ○
select_from_sockets/3 | ソケットリストからデータを受信しているソケットを抽出します | ○ | ○ | ○
host2ip/4 | ホスト名をＩＰアドレスに変換します | ○ | ○ | ○
B | ssl_client_connect/4 | SSLソケット接続の接続要求を行います |  | ○ | ○
ssl_socket_send/2 | SSLソケットにデータを送信します |  | ○ | ○
ssl_socket_receive/2 | SSLソケットからデータを受信します |  | ○ | ○
ssl_socket_close/1 | SSLソケット接続を終了します |  | ○ | ○
C | ssl_cert_load_cafile/3 | サーバー証明書ファイル(CA)で認証を行いソケット接続を確立します |  | ○ | ○
ssl_cert_load_file/4 | サーバー証明書ファイル(CA)と秘密鍵ファイル(Private Key)で認証を行いソケット接続を確立します |  | ○ | ○
ssl_cert_load_data/4 | サーバー証明書データ(CA)と秘密鍵データ(Private Key)で認証を行いソケット接続を確立します |  | ○ | ○
ssl_cert_send/2 | 認証されたソケットにデータを送信します |  | ○ | ○
ssl_cert_receive/3 | 認証されたソケットからデータを受信します |  | ○ | ○
ssl_cert_close/1 | SSLコンテキストを解放します。 |  | ○ | ○
D | socket_download/2 | ソケットからデータを受信しファイルへ書き込みます | ○ | ○ | ○
socket_ssl_download/2 | SSLソケットからデータを受信しファイルへ書き込みます |  | ○ | ○
E | unix_client_connect/2 | UNIXソケットよりソケット接続の接続要求を行います | ○ | × | ○
unix_server_create/2 | UNIXソケットよりソケットサーバーを生成します | ○ | × | ○
unix_server_close/2 | UNIXソケットでのソケット接続を終了します | ○ | × | ○
F | check_socket_receivable/1 | ソケットに読み込みデータがあるかを確認します | ○ | ○ | ○
check_socket_sendable/1 | ソケットディスクリプタの接続確立状況を確認します | ○ | ○ | ○
G | ping/2 | ネットワーク疎通を確認します | ○ | × | ○
ping_async/2 | ネットワーク疎通確認をソケットを通して行います | ○ | × | ○
H | ws_set_log_level/1 | libwebsocketsのログ出力レベルを指定する | ○ | × | ○
ws_set_client_certificate_file_path/1 | クライアント側certificate fileのパスを指定する | ○ | × | ○
ws_set_client_private_key_file_path/1 | クライアント側private key fileのパスを指定する | ○ | × | ○
ws_create_context/3 | クライアント側のCONTEXTを生成する | ○ | × | ○
ws_delete_context/1 | CONTEXTを削除する | ○ | × | ○
ws_connect/10 | サーバに接続して、生成されたSESSIONを返す | ○ | × | ○
ws_close/1 | 接続SESSIONを閉じる | ○ | × | ○
ws_is_close/2 | 接続SESSIONを閉じる | ○ | × | ○
ws_sub_protocol/2 | 指定されたSESSIONのsub-protocolを返す | ○ | × | ○
ws_read_text/3 | テキストデータを読み込む | ○ | × | ○
ws_write_text/2 | テキストデータを送信する | ○ | × | ○
ws_write_atom_list/2 | アトム並びリストのテキストデータを送信する | ○ | × | ○
ws_read_list/3 | バイナリデータを読み込む | ○ | × | ○
ws_write_list_binary/2 | バイナリデータを送信する | ○ | × | ○
ws_write_pong/1 | PONGを送信する | ○ | × | ○
ws_version/1 | バージョン情報を取得する | ○ | × | ○

※1) 通常とはOpenSSLライブラリ、Cryptoライブラリがインストールされていない状態を示します。
上記一覧で示している述語は、８つのグループ（A～H）に分けられます。

Aグループ | 通常ソケット関連述語
Bグループ | SSLソケット関連述語
Cグループ | 証明書認証関連述語
Dグループ | ファイルダウンロード関連述語
Eグループ | UNIXソケット関連述語
Fグループ | 読込みデータ及び接続の確認関連述語
Gグループ | 疎通確認関連述語
Hグループ | WEBソケット関連述語

コンパイルされたダイナミックローディングライブラリは次です。

[Windows]
${AZProlog} = インストールディレクトリ

${AZProlog} libextsocket.dll
${AZProlog} libextsocket_ssl.dll

[Linux]
${AZProlog} = /usr/local またはインストールディレクトリ
${AZProlog}lib/azprolog/ext/socket.so
${AZProlog}lib/azprolog/ext/socket_ssl.so
${AZProlog}lib/azprolog/ext/websock.so

[Mac]
${AZProlog} = /Applications/azprolog.app/Contents/az_home/ またはインストールディレクトリ
${AZProlog}lib/azprolog/ext/socket.dylib
${AZProlog}lib/azprolog/ext/socket_ssl.dylib
${AZProlog}lib/azprolog/ext/websock.dylib

### 9-7-2.インストール

##### Windowsの場合

OpenSSLをインストールする場合は、OpenSSLサイトよりインストーラーをダウンロードし起動してインストールを行います。
Cryptoをインストールする場合は、Cryptoサイトよりライブラリまたはコンパイルソース一式をダウンロードします。
なお、コンパイルソース一式をダウンロードする場合は、コンパイルを実施しライブラリの生成を行います。
※ライブラリ生成後は、Windowsシステム・ディレクトリ(WindowsSystem32)にコピーします。
【OpenSSLのダウンロード】
http://slproweb.com/products/Win32OpenSSL.html
Win32 OpenSSL v1.0.2
または
Win64 OpenSSL v1.0.2

【Cryptoのダウンロード】
http://www.cryptopp.com/#download

バイナリのダウンロードは、サイトの中ごろにあるリンクをクリックして行います。
「FIPS 140-2 Conformance」
・Crypto++ Library 5.3.0 (32-bit and 64-bit Windows DLL, calling application must be compiled with MSVC 2005) [download package] [download PGP signature] [certificate #819]

→[download package]のリンクをクリックします。（2015.03.09現在でバージョンは5.3.0が最新です)

インストール後は、以下に示すライブラリファイルが Windowsシステム・ディレクトリ(WindowsSystem32)に存在するか確認します。もし、１つでもライブラリファイルが存在しない場合は、ライブラリのロード述語で失敗する可能性があります。
- ssleay32.dll
- libeay32.dll
- cryptopp.dll

##### Linuxの場合

    $ sudo apt-get install openssl
    $ sudo apt-get install libssl-dev

##### Macの場合

    $ sudo port install openssl

### 9-7-3.動作確認

##### 通常ソケットの場合

AZ-Prolog を立ち上げ、ソケットライブラリがロードできるか確認します。

    $ prolog
    | ?-dlib_require(socket).
    yes
    | ?-

通常ソケット関連の述語を利用する場合は、上記のように必ず dlib_require で socket ライブラリをロードしてください。

##### WEBソケットの場合

AZ-Prolog を立ち上げ、ソケットライブラリがロードできるか確認します。

    $ prolog
    | ?-dlib_require(websock).
    yes
    | ?-

WEBソケット関連の述語を利用する場合は、上記のように必ずdlib_requireで、websockライブラリをロードしてください。

##### SSLソケットの場合

AZ-Prolog を立ち上げ、SSLソケットライブラリがロードできるか確認します。

    $ prolog
    | ?-dlib_require(socket_ssl).
    yes
    | ?-

SSLソケット関連の述語を利用する場合は、上記のように必ず dlib_require でsocket_ssl ライブラリをロードしてください。
なお、通常またはSSLソケットライブラリのロードを行ってもプラットフォームで利用できる述語が異なりますので御注意ください。
「9-7-1.概要」の表（サポート状況）を参照ください。

### 9-7-4.述語の組み合せ利用例

ソケット関連の述語は単独で利用できないものが多く、組み合せで利用しなければなりません。
述語の組み合せ利用例として以下に紹介します。

##### Ａグループ：通常ソケット関連述語

ソケットサーバー生成とクライアント接続の述語記述例
＜サーバー側＞

###### ソケットサーバーを生成する

使用述語: server_create、select_from_sockets、server_accept、socket_receive_list

    go:-server_create('5000',Acc),
        repeat,
        all_acc(1,WatchList),
        select_from_sockets(20000,[Acc|WatchList],ReceivedList),
        member(Sock,ReceivedList),
        rec_do(Acc,Sock,Data),
        write(Sock=Data),nl,
        fail.
    rec_do(A,A,_):- !,server_accept(A,Host,S),assert('$acc$'(S)),fail.
    rec_do(_,S,D):- socket_receive_list(S,D),length(D,N),N>0,!.
    rec_do(_,S,_):- socket_close(S),retract('$acc$'(S)),fail.
    all_acc(N,[A|L]):- clause('$acc$',1,N,'$acc$'(A)),!,NN is N+1,all_acc(NN,L).
    all_acc(_,[]).
    ?-go.
    4=[97,98,99,100,101,102,103,13,10]

ソケットサーバーのサーバー生成述語を定義し、その後述語を実行しクライアントからの接続待機を行う。
上記の例ではソケットサーバーを5000ポートで生成し、クライアントからの接続を待機する。
その後、クライアントからの接続が確立された場合は、データ受信を行い受信データをリストで表示している。

###### クライアント側で接続を試す

    $ telnet localhost 5000
    Trying 127.0.0.1...
    Connected to localhost.
    Escape character is '^]'.
    abcdefg

telnetコマンドでソケットサーバー(localhost)に5000ポートで接続し データ(abcdefg) を入力
＜クライアント側：同期＞

###### ソケットサーバーに接続しデータを送信する

使用述語: client_connect、socket_send、socket_close

    test:-
     client_connect('127.0.0.1','5000',S),
     socket_send(S,'TEST'),
     socket_close(S).
    ?-test.
    yes
    ?-

ソケットサーバーへ接続しデータを送信する述語を定義し、その後述語を実行しソケットサーバーへデータを送信する。
上記の例では、ソケットサーバー(127.0.0.1)に5000ポートで接続しデータを送信している。

###### Web上のコンテンツを取得する

使用述語: client_connect、socket_send、socket_from_sockets、socket_receive_list、socket_close

    get_request(Url):-
     client_connect('127.0.0.1','80',S),
     name(CR,[10]),
     atom_concat('GET ',Url,P1),
     atom_concat(P1,' HTTP/1.1',P2),
     atom_concat(P2,CR,P3),
     atom_concat(P3,'Host: 127.0.0.1',P4),
     atom_concat(P4,CR,P5),
     atom_concat(P5,'Connection: Close',P6),
     atom_concat(P6,CR,P7),

     atom_concat(P7,CR,Get),
     socket_send(S,Get),
     get_all(S,"""",LAns),
     socket_close(S),
     name(Ans,LAns),
     write(Ans).
    get_all(Sock2,Bef,Ans):-
        select_from_sockets(20000,[Sock2],[Sock3]),
        socket_receive_list(Sock3,Out),length(Out,N),N>0,!,
        append(Bef,Out,NextBef),
        get_all(Sock3,NextBef,Ans).
    get_all(Sock2,A,A).
    ?-get_request('/index_test.html').
    HTTP/1.1 200 OK
    Date: Mon, 02 Dec 2013 09:33:50 GMT
    Server: Apache/2.2.22 (Ubuntu)
    Last-Modified: Mon, 02 Dec 2013 09:29:57 GMT
    ETag: ""161652-2d-4ec89d2c4b7a4""
    Accept-Ranges: bytes
    Content-Length: 45
    Vary: Accept-Encoding
    Connection: close
    Content-Type: text/html

    ‹html›
    ‹body›
    Test Test Test
    ‹/body›
    ‹/html›
    yes
    ?-

WEBサーバーからGETリクエストでコンテンツを取得する述語を定義し、その後述語を実行し取得したコンテンツを表示する。
上記の例ではWEBサイト(127.0.0.1)にHttpポート(80)で接続し、GETリクエストで指定のコンテンツを取得し表示している。

###### Proxy経由でWeb上のコンテンツを取得する

使用述語: client_connect、socket_send、socket_from_sockets、socket_receive_list、socket_close

    get_from_proxy(Url):-
     client_connect('127.0.0.1','3128',S),
     name(CR,[10]),
     atom_concat('GET ',Url,P1),
     atom_concat(P1,' HTTP/1.1',P2),
     atom_concat(P2,CR,P3),
     atom_concat(P3,'Host: 127.0.0.1',P4),
     atom_concat(P4,CR,P5),
     atom_concat(P5,'Connection: Close',P6),
     atom_concat(P6,CR,P7),
     atom_concat(P7,CR,Get),
     socket_send(S,Get),
     get_all(S,"""",LAns),
     socket_close(S),
     name(Ans,LAns),
     write(Ans).
    get_all(Sock2,Bef,Ans):-
        select_from_sockets(20000,[Sock2],[Sock3]),
        socket_receive_list(Sock3,Out),length(Out,N),N>0,!,
        append(Bef,Out,NextBef),
        get_all(Sock3,NextBef,Ans).
    get_all(Sock2,A,A).
    ?-get_from_proxy('http://www.yahoo.co.jp').
    HTTP/1.0 200 OK
    Date: Mon, 02 Dec 2013 09:11:33 GMT
    P3P: policyref=""http://privacy.yahoo.co.jp/w3c/p3p.xml"", CP=""CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE GOV""
    Expires: -1
    Pragma: no-cache
    Cache-Control: private, no-cache, no-store, must-revalidate
    X-XRDS-Location: http://open.login.yahoo.co.jp/openid20/www.yahoo.co.jp/xrds
    Vary: Accept-Encoding
    Content-Type: text/html; charset=utf-8
    X-Cache: MISS from localhost
    X-Cache-Lookup: MISS from localhost:3128
    Via: 1.0 localhost (squid/3.1.19)
    Connection: close

    　・　　　<== コンテンツ表示を省略
    　・　　　<== コンテンツ表示を省略
    　・　　　<== コンテンツ表示を省略

    ‹/body›
    ‹/html›
    yes
    ?-

Proxyサーバー経由でWEBサーバーからGETリクエストでコンテンツを取得する述語を定義し、その後述語を実行し取得したコンテンツを表示する。
上記の例ではProxyサーバー(127.0.0.1)経由でWebサイト(localhost)にHttpポート(80)で接続し、GETリクエストで指定のコンテンツを取得し表示している。

##### Ｂグループ：SSLソケット関連述語

SSLソケットクライアント接続の述語記述例

###### SSLソケットでWeb上のコンテンツを取得する

使用述語: ssl_client_connect、ssl_socket_send、ssl_socket_receive、ssl_socket_close

    get_ssl_request(Host):-
        host2ip(Host,GH,AH,IP),
        ssl_client_connect(IP,'443','RSA',S),
        name(C,[10]),
        D1 = 'GET / HTTP/1.1',
        atom_concat(D1,C,D2),
        atom_concat(D2,'Host: ',D3),
        atom_concat(D3,Host,D4),
        atom_concat(D4,':443',D5),
        atom_concat(D5,C,D6),
        atom_concat(D6,'Connection: Close',D7),
        atom_concat(D7,C,D8),
        atom_concat(D8,C,Data),
        ssl_socket_send(S,Data),
        get_all(S,"""",LAns),
        name(Ans,LAns),
        write(Ans),nl,
        ssl_socket_close(S).
    get_all(Sock2,Bef,Ans):-
        ssl_socket_receive(Sock2,Out),name(Out,OutL),length(OutL,N),N>0,!,
        append(Bef,OutL,NextBef),
        get_all(Sock2,NextBef,Ans).
    get_all(Sock2,A,A).
    ?-get_ssl_request('www.verisign.co.jp').
    HTTP/1.1 200 OK
    Server: """"
    Date: Mon, 02 Dec 2013 05:51:28 GMT
    Content-type: text/html
    Connection: close

    ‹!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.01 Transitional//EN"" ""http://www.w3.org/TR/html4/loose.dtd""›
    ‹html lang=""ja""›
    ‹head›
    ‹link rel=""canonical"" href=""https://www.verisign.co.jp/""›
      ・　　　<== コンテンツ表示を省略
      ・　　　<== コンテンツ表示を省略
      ・　　　<== コンテンツ表示を省略
    ‹/body›
    ‹/html›

    yes
    ?-

指定されたホストにSSLで接続し、GETリクエストでコンテンツを取得する述語を定義し、その後述語を実行し取得したコンテンツを表示する。
上記の例ではベリサインのサイト(www.verisign.co.jp)にSSLで接続し、GETリクエストでトップサイトのコンテンツを取得し表示している。

##### Ｃグループ：証明書認証関連述語

サーバー証明書ファイル(CA)で認証し、ソケットクライアント接続の述語記述例

###### サーバー証明書ファイル(CA)で認証し、ソケットクライアント接続を行ってデータの送受信を行う

使用述語: client_connect、ssl_cert_load_cafile、ssl_cert_send、ssl_cert_receive、socket_close、ssl_cert_close

    test:-
        IP='127.0.0.1',
        CERT_FILE='server.pem',
        client_connect(IP,'3000',S),
        ssl_cert_load_cafile(S,CERT_FILE,S2),
        name(C,[10]),
        Data1='Get Data Request',
        atom_concat(Data1,C,Data),
        ssl_cert_send(S2,Data),
        get_all(S2,"""",LAns),
        name(Ans,LAns),
        write(Ans),nl,
        socket_close(S),
        ssl_cert_close(S2).
    get_all(SN,Bef,Ans):-
        ssl_cert_receive(SN,Out,Sz),name(Out,OutL),length(OutL,N),N>0,!,
        append(Bef,OutL,NextBef),
        get_all(SN,NextBef,Ans).
    get_all(SN,A,A).
    ?-test.
    Welcome !! Test Certificate Data
    yes
    ?-

ソケットサーバーに認証接続を行いデータの送受信を行う述語を定義し、その後述語を実行し受信データを表示する。
上記の例ではソケットサーバー(localhost)にクライアント接続し証明書ファイル認証を行い、その後データの送受信を行って受信データを表示している。

##### Ｄグループ：ファイルダウンロード関連述語

ソケットサーバーからファイルをダウンロードする述語記述例

###### ソケットサーバーよりバイナリファイルをダウンロードする

使用述語: client_connect、socket_send、socket_download、socket_close

    test:-
         client_connect('127.0.0.1','80',S),
         P1='GET /icon.zip HTTP/1.1',
         name(C,[10]),
         atom_concat(P1,C,P2),
         atom_concat(P2,'Host: 127.0.0.1',P3),
         atom_concat(P3,C,P4),
         atom_concat(P4,'Connection: Close',P5),
         atom_concat(P5,C,P6),
         atom_concat(P6,C,Get),
         socket_send(S,Get),
         socket_download(S, 'icon.zip'),
         socket_close(S).
    ?-test.
    yes
    ?-

ソケットサーバーにクライアント接続しGETリクエストでファイルをダウンロードする述語を定義し、その後述語を実行しファイルをダウンロードする。
上記の例ではWebサイト(localhost)にHttpポート(80)で接続し、GETリクエストでバイナリファイルをダウンロードしている。

##### Ｅグループ：UNIXソケット関連述語

UNIXソケットサーバー生成とクライアント接続の述語記述例
＜サーバー側＞

###### UNIXソケットサーバーを生成する

使用述語: unix_server_create、select_from_sockets、socket_send、server_accept、socket_receive_list、socket_close

    go:-unix_server_create('/tmp/test.sock',Acc),
        repeat,
        all_acc(1,WatchList),
        select_from_sockets(20000,[Acc|WatchList],ReceivedList),
        member(Sock,ReceivedList),
        rec_do(Acc,Sock,Data),
        write(Sock=Data),nl,
        name(AData,Data),
        socket_send(Sock,AData),
        fail.
    rec_do(A,A,_):- !,server_accept(A,Host,S),assert('$acc$'(S)),fail.
    rec_do(_,S,D):- socket_receive_list(S,D),length(D,N),N>0,!.
    rec_do(_,S,_):- socket_close(S),retract('$acc$'(S)),fail.
    all_acc(N,[A|L]):- clause('$acc$',1,N,'$acc$'(A)),!,NN is N+1,all_acc(NN,L).
    all_acc(_,[]).
    ?-go.
    4=[72,101,108,108,111]

UNIXソケットサーバーのサーバー生成述語を定義し、その後述語を実行しクライアントからの接続待機を行う。
上記の例ではUNIXソケットサーバーをUNIXソケット(/tmp/test.sock)で生成し、クライアントからの接続を待機する。
その後、クライアントからの接続が確立された場合は、データ受信を行い受信データをリストで表示しクライアント側へ受信データを返信している。

＜クライアント側＞

###### UNIXソケットサーバーに接続しデータを送受信する

使用述語: unix_client_connect、socket_send、select_from_sockets、socket_receive_list、socket_close

    test:-
        unix_client_connect('/tmp/test.sock',S),
        socket_send(S,'Hello'),
        get_all(S,"""",LAns),
        name(Ans,LAns),
        write(Ans),nl,
        socket_close(S).
    get_all(Sock2,Bef,Ans):-
        select_from_sockets(20000,[Sock2],[Sock3]),
        socket_receive_list(Sock3,Out),length(Out,N),N>0,!,
        append(Bef,Out,NextBef),
        get_all(Sock3,NextBef,Ans).
    get_all(Sock2,A,A).
    ?-test.
    Hello
    yes
    ?-

UNIXソケットサーバーへ接続しデータを送受信する述語を定義し、その後述語を実行しUNIXソケットサーバー間でデータの送受信を行う。
上記の例では、UNIXソケット(/tmp/test.sock)でUNIXソケットサーバーに接続しデータを送信している。
その後、UNIXソケットサーバーからのデータを受信し、受信データを表示している。

##### Ｆグループ：データの送受信のノンブロッキング処理

ソケットのノンブロッキング処理の記述例

###### ノンブロッキング処理で送信、受信を行う

使用述語: client_connect、check_socket_sendable、socket_send、check_socket_receivable、socket_receive、socket_close

    test:-
        client_connect('127.0.0.1','5000',S),
        repeat,
            s_sleep(100),
            check_socket_sendable(S),
            socket_send(S,'Client Data'),
        repeat,
            s_sleep(100),
            check_socket_receivable(S),
            socket_receive(S,Data),
        write(Data),nl,
        socket_close(S).
    ?-test.
    Server Data
    yes
    ?-

上の項目まで説明してきたsendやreceiveなどは、全てブロッキング処理になり、sendの場合は「相手が受信できる状態までブロックする」、receiveの場合は「相手からのデータが届くまでブロックする」。

一つのソケットのやり取りを行うのであれば、ブロッキング処理でも問題ありませんが、複数のソケットを受信する場合や、受信待ちの間に別の作業を挟みたい場合はノンブロッキング処理を使用する必要があります。

check_socket_sendable(S)

socket_send の前に置き、相手が受信できない状態であればfailする。相手が受信可能であれば成功し、次に続くsend処理もノンブロッキングで実施される。

check_socket_receivable(S)

socket_receive の前に置き、ソケット宛の受信データが来ていない場合はfailする。受信データがあれば成功し、receive処理が実施できる。

上記の例では、ソケットサーバー(127.0.0.1)に5000ポートで接続し、接続後送信可能確認を行い、送信できる状態であればデータ送信、出来なければsleepしながら繰り返し送信確認。
送信後、受信データがデータを受信、なければsleepしながら繰り返し受信確認、データの受信後、データを表示している。

注意） 現在ノンブロッキング処理は非SSLのAグループとEグループでしか使用できません。

##### Gグループ：疎通確認関連述語

ネットワーク上のサーバー疎通確認述語記述例

###### ICMPを使用したサーバーの疎通確認を行う

使用述語:ping、ping_async、check_socket_receivable、socket_close

    test1:-
     ping('127.0.0.1',2).
    ?-test1.
    yes

    test2:-
        ping_async('127.0.0.1',S),
        repeat,
        s_sleep(100),
        check_socket_receivable(S),
        socket_receive_list(S,L),
        write(receive=L),nl,
        length(L,Len),
        (Len > 0->write('Replay');write('No Replay')),
        socket_close(S).
    ?-test2.
    receive=[69,0,0,28,140,241,64,0,64,1,175,237,127,0,0,1,127,0,0,1,8,0,247,255,0,0,0,0]
    Replay
    yes
    ?-

ping(Server,Timeout)はサーバーに対しpingを実施、Timeout(秒)値以内で応答があれば成功し、なければfailします。
ping_async(Server,Socket)はICMPを送るとともにソケットを生成、ノンブロッキング処理で相手からの応答を待ちます。
そのため、ping_asyncの場合はソケット生成後の受信処理、終了処理を必要とします。

上記の例では、１つ目の述語が２秒のタイムアウトでpingの疎通確認を行う。２つ目の述語はソケットの生成を行いながらICMPの送信、 受信はcheck_socket_receivableが成功するまでs_sleepしながら待ち、受信確認ができれば受信データの表示をしている。

注意）ping処理はroot権限でないと使用ができません。

##### Hグループ：WEBソケット関連述語

WEBソケットサーバー生成とクライアント接続例

＜サーバー側＞

nodejsがインストールされていない場合はインストールしておきます。
ダウンロードサイト:http://nodejs.org/

    $ cp ~/ダウンロード/node* .
    $ tar xzf node-v0.10.26.tar.gz
    $ cd  node-v0.10.26
    $ ./configure
    $ make
    $ sudo make install

パッケージにはnodejsを使ったサーバーのサンプルが含まれています。

これを任意の場所にコピーし、ここにwebsocketモジュールをインストールします

    $ cp -r /usr/local/share/azprolog/sample/ext/websock_node_server .
    $ cd websock_node_server
    $  npm install websocket

SSLを使用しない場合のサーバー立ち上げ

    $ node sample.js

SSL使用、クライアント認証付きのサーバー立ち上げ

    $ node sample-client-cert.js

＜クライアント側＞
パッケージにAZ-PrologのWebソケットを使ったクライアントのサンプルが含まれています。

    $ cd /usr/local/share/azprolog/sample/ext/
    $ prolog -s websock.pl
    | ?- t.                   % ssl を使用しない場合
        ＜サーバーとの通信テストが開始され、画面に内容が表示されます。＞
         :
    | ?- t2.                   % SSL使用、クライアント認証付き
        ＜サーバーとの通信テストが開始され、画面に内容が表示されます。＞

処理のそれぞれの詳細はプログラムをご一読ください。

▲