(* 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 sock f cap = let rec loop cap = 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 sock f cap = let ((clientsock, clientcap), cap) = accept sock cap in putStrLn "Opened connection"; (Thread.fork :> (unit -A> unit) → Thread.thread) (λ _ → handleClient clientsock f clientcap; putStrLn "Closed connection"); acceptLoop sock f cap let serve port f = let (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 = match argv with | [port] → EchoServer.serve (int_of_string port) serverFun | _ → failwith "Usage: echoServer.aff PORT\n" in main (getArgs ())