packages feed

alms-0.4.9: examples/netcat.alms

(* Poor programmer's telnet *)

open Prim.Socket

local
  open IO
with
  let rec sendThread (sock: socket): unit =
    if hIsEOF stdin
      then
        shutdown sock ShutdownSend
      else
        try
          send sock (getLine () ^ "\r\n");
          sendThread sock
        with
          IOError _ -> ()

  let rec recvThread (sock: socket): unit =
    try
      putStr (recv sock 1024); recvThread sock
    with
      IOError _ -> ()
end

let setupConnection (addr: sockAddr): socket =
  let s = socket AF_INET Stream defaultProtocol in
    connect s addr;
    s

let teardownConnection (sock: socket): unit =
  close sock

let getAddr (): sockAddr =
  match getArgs () with
  | Cons(host, Cons(port, Nil))
      -> let info = AddrInfo(Nil[addrInfoFlag], AF_INET,
                             Stream, defaultProtocol,
                             SockAddrInet(PortNum 0, 0), None[string]) in
         (match getAddrInfo (Some info) (Some host) (Some port) with
          | Cons (AddrInfo (_, _, _, _, sockAddr, _), _) -> sockAddr
          | _ -> failwith ("Could not resolve address "^host^":"^port))
  | _ -> failwith ("Usage: " ^ getProgName () ^ " HOST SERVICE")

let main () =
  let sock = setupConnection (getAddr ()) in
  let wait = Future.new (fun () -> recvThread sock) in
    sendThread sock;
    Future.sync wait;
    teardownConnection sock

in main ()