(* Echo server written using state-tracked sockets. *) #load "libsocketcap3" module EchoServer = struct open SocketCap (* This is a bit different than the version in the paper, because * it uses exceptions. *) let rec clientLoop f sock !cap = let str = recv sock 1024 cap in send sock (f str) $> cap; clientLoop f sock cap let rec acceptLoop f sock !cap = let (clientsock, clientcap) = accept sock cap in putStrLn "Opened connection"; Thread.fork (λ _ → catchReady (λ _ → clientLoop f clientsock clientcap) (clientsock, λ clientcap → close clientsock clientcap; putStrLn "Closed connection")); acceptLoop f sock cap let serve port f = let (sock, !cap) = socket () in bind sock port $> cap; listen sock $> cap; acceptLoop f sock cap end let serverFun (s: string) = s let main = function | [port] → EchoServer.serve (int_of_string port) serverFun | _ → failwith "Usage: echoServer.aff PORT\n" in main (getArgs ())