alms-0.4.9: examples/echoServer.alms
(* Echo server written using state-tracked sockets. *)
#load "libsocketcap"
module EchoServer = struct
open ASocket
(* This is a bit different than the version in the paper, because
* it uses exceptions. *)
let handleClient['t] (sock: 't socket) (f: string -> string)
(cap: 't connected) : unit =
let rec loop (cap: 't connected): unit =
let (str, cap) = recv sock 1024 cap in
let cap = send sock (f str) cap in
loop cap
in try
loop cap
with SocketError _ -> ()
let rec acceptLoop['t] (sock: 't socket) (f: string -> string)
(cap: 't listening) : unit =
let (Pack('s, clientsock, clientcap), cap) = accept sock cap in
putStrLn "Opened connection";
(Thread.fork :> (unit -o unit) -> Thread.thread)
(fun () -> handleClient clientsock f clientcap;
putStrLn "Closed connection");
acceptLoop sock f cap
let serve (port: int) (f: string -> string) =
let Pack('t, sock, cap) = socket () in
let cap = bind sock port cap in
let cap = listen sock cap in
acceptLoop sock f cap
end
let serverFun (s: string) = s
let main (argv: string list) =
match argv with
| Cons (port, Nil) -> EchoServer.serve (int_of_string port) serverFun
| _ -> failwith "Usage: echoServer.aff PORT\n"
in main (getArgs ())