Source

ocaml-bert / echo_server.ml

Full commit
open Sys;;
open Unix;;

let start_tcp_server addr =
  let sock  = socket PF_INET SOCK_STREAM 0 in
    try 
      setsockopt sock SO_REUSEADDR true;
      bind sock addr;
      listen sock 10;
      sock
    with z-> close sock; raise z;; 

let start_default_tcp_server port = 
  start_tcp_server (ADDR_INET (inet_addr_any, port));;

let tcp_server treat_connection = 
  ignore (signal sigpipe Signal_ignore);
  let port = 10009 in
    Printf.printf "staring server in %d ... %!" port;
    let sock = start_default_tcp_server port  in
      print_endline "[done]";
      while true do
	let client = accept sock in
	  treat_connection client
      done;;

let accept_callback (csock, caddr) = 
(*  print_endline (string_of_inet_addr ADDR_UNIX (addr)); *)
  begin match caddr with
    | ADDR_INET(caller, _)->
	prerr_endline ("connection from " ^ string_of_inet_addr caller );
    | ADDR_UNIX(_)->
	prerr_endline "connection from the unix domain ... ";
  end;
  let recv_term sock = 
    let buf = String.create 1024 in
    let rec recv_ start toread = 
      let len = recv sock buf start toread [MSG_PEEK] in
	prerr_endline ((string_of_int len) ^ " bytes recv'd");
	begin match Bert.decode_binary buf with 
	  | Bert.More(length) -> recv_ start (len+length+toread);
	  | Bert.Ok(term, remain) ->   Bert.print_erlterm term;
	  | Bert.None ->      print_endline "error?";
	end;
    in recv_ 0 2 in
  let _ = recv_term csock in
    
    (*     prerr_endline buffer; *)
    close csock;
    prerr_endline "----------------";;

(* print_endline (string_of_inet_addr ADDR_UNIX(addr));  *)
handle_unix_error tcp_server accept_callback;;