(* 使い方: ocaml unix.cma #use "util_sample..ml";; 名前からIPアドレスの配列を返す。 get_ip "google.co.jp";; それぞれhttp1.0,http1.1で通信してindex.htmlをとってくる。 get_html10 "caml.inria.fr";; get_html11 "caml.inria.fr";; unixドメインの通信を試す。rubyプログラムが起動している必要がある。 シェルで別途 ruby unix_test.rb /tmp/socket としておく。 ここでocamlインタプリタ内で pfunix_test "/tmp/socket" "test";; とするとrubyプログラムにtestと表示される。なお最初に/tmp/socket というファイルがあるとエラーになる。 パイプを試す。例えばHelloと3回表示するだけのrubyプログラムhello.rb の内容をocamlで使いたいとする。次のようにする。 pipe_test "ruby hello.rb";; カレントディレクトリのファイルの名前をもらいたいときは pipe_test "ls";; *) (* 名前からIPアドレスを取得 *) let get_ip name = let host_entry = Unix.gethostbyname name in Array.map Unix.string_of_inet_addr host_entry.Unix.h_addr_list;; (* htmlファイルを取得 *) let connect host port = let addr = Unix.gethostbyname host in let s = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in Unix.connect s (Unix.ADDR_INET(addr.Unix.h_addr_list.(0), port)); s;; let get str sock = let a = Unix.in_channel_of_descr sock in ignore(Unix.write sock str 0 (String.length str)); try while true do print_string (input_line a); print_newline(); done with End_of_file -> close_in a;; (* 例 get_html1.0 "caml.inria.fr";; *) let get_html10 name = let str = "GET /index.html HTTP/1.0\r\n\r\n" in let sock = connect name 80 in get str sock;; let get_html11 name = let str1 = "GET /index.html HTTP/1.1\n" in let str2 = "Host:"^name^"\n" in let str3 = "Connection:close\n\n" in let sock = connect name 80 in get (str1^str2^str3) sock;; (* Unixドメインでの通信。rubyプログラムなどが起動している必要がある *) let pfunix_test name test_str= let sockfd = Unix.socket Unix.PF_UNIX Unix.SOCK_STREAM 0 in Unix.connect sockfd (Unix.ADDR_UNIX name); ignore(Unix.write sockfd test_str 0 (String.length test_str)); Unix.close sockfd; Unix.system ("rm "^name);; (* パイプのプログラム *) let sub_func a return = try while true do return := (input_line a)::!return; done; with End_of_file -> ();; let pipe_test command = let std_in,std_out = Unix.pipe () in let rfd,wfd = Unix.pipe () in let return = ref [] in Unix.dup2 Unix.stdin std_in; Unix.dup2 Unix.stdout std_out; if Unix.fork () = 0 then begin Unix.dup2 wfd Unix.stdout; Unix.close wfd; Unix.close rfd; ignore(Unix.system command); end else begin Unix.dup2 rfd Unix.stdin; Unix.close rfd; Unix.close wfd; let a = Unix.in_channel_of_descr Unix.stdin in sub_func a return; end; Unix.dup2 std_in Unix.stdin; Unix.dup2 std_out Unix.stdout; Unix.close std_in; Unix.close std_out; !return;;