Skip to content

Instantly share code, notes, and snippets.

@DarinM223
Last active August 13, 2023 01:27
Show Gist options
  • Save DarinM223/d8647838052df0e47d6e4d9e34bc0f95 to your computer and use it in GitHub Desktop.
Save DarinM223/d8647838052df0e47d6e4d9e34bc0f95 to your computer and use it in GitHub Desktop.
Example of a TCP server using CML in MLton
$(SML_LIB)/basis/basis.mlb
$(SML_LIB)/basis/mlton.mlb
$(SML_LIB)/smlnj-lib/INet/inet-lib.mlb
$(SML_LIB)/cml/cml.mlb
server.sml
(* To test the server: run `nc localhost 8989` in a terminal. *)
type passive_socket = (INetSock.inet, Socket.passive Socket.stream) Socket.sock
fun connMain s =
let
fun count 0 = SockUtil.sendStr (s, "Bye!\r\n")
| count n =
( SockUtil.sendStr (s, "Hello " ^ (Int.toString n) ^ "\r\n")
; CML.sync (CML.timeOutEvt (Time.fromReal 0.5))
; count (n - 1)
)
in
count 10;
print "Closing the connection.\n";
Socket.close s
end
fun acceptLoop serverSock =
let
val (s, _) = Socket.accept serverSock
in
print "Accepted a connection.\n";
CML.spawn (fn () => connMain s);
acceptLoop serverSock
end
fun cmlMain () =
let
val s: passive_socket = INetSock.TCP.socket ()
in
Socket.Ctl.setREUSEADDR (s, true);
Socket.bind (s, INetSock.any 8989);
Socket.listen (s, 5);
print "Entering accept loop...\n";
acceptLoop s
end
val _ =
let open MLton.Signal
in setHandler (Posix.Signal.pipe, Handler.ignore); RunCML.doit (cmlMain, NONE)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment