OCaml Network Servers

I'm wading through some of the OCaml documentation, and finding out how easy it is to write simple network servers in the language. I'm trying to stay away (far away) from libraries that are not in the standard distribution for now, and while I have not yet learned how to handle exceptions (such as the Fatal error: exception End_of_file which occurs at every client disconnect below -- but note that only the handling process is affected) here is a simple echo server:

sam@caveman:~/tmp/ocaml/unix$ cat echod.ml

(* interpreter:
#load "unix.cma";;
*)

open Unix;;
open Printf;;

let rec echo_server client_in_channel client_out_channel =
        let s = input_line client_in_channel in
        fprintf client_out_channel "%s\n" s;
        flush client_out_channel;
        echo_server client_in_channel client_out_channel;;

let _ =
        let server_inetaddr = inet_addr_of_string "127.0.0.1" in
        let server_sockaddr = ADDR_INET( server_inetaddr, 8000) in
        establish_server echo_server server_sockaddr;;

Compiling and linking the daemon is trivial, once you figure out that the script you put together in the interpreter using #load "unix.cma";; is a syntax error to the compiler, and discover how to use ocamlfind to load libraries for ocamlc. It feels quite irritating me to wrap my head around the (seemingly) completely different ways in which libraries are used between the ocaml interpreter and when compiling with ocamlc. Perhaps one day I will figure that out as well, but for now, here is how I compiled my echod echo server daemon:

sam@caveman:~/tmp/ocaml/unix$ ocamlfind ocamlc -o echod -package unix -linkpkg echod.ml

The next logical step was to put together a simple chat server: keeping track of multiple clients and managing inter-client communication.

But first I decided to figure out once-and-for-all to get a handle on the tooling and solve that "ocamlfind ocamlc" vs. "ocaml and #load" issue. It turns out that the tool ocamlmktop is to be used to create a toplevel interpreter if you want to include such libraries. Luckily, ocamlmktop can be used with ocamlfind in a straightforward and obvious way:

sam@caveman.org:~tmp/ocaml/unix$ ocamlfind ocamlmktop -o mytop -package unix -linkpkg

And now running ./mytop gets me the ability to simply open Unix as usual, and run my script for iterative development before full compilation. So now, back to a chat server.

(Work in progress.)

changed March 7, 2008