(* In this program, we'll write a very simple TCP server. The server will read
* a single line from a client, print it out, and then close the connection. *)
open Core.Std open Async.Std
(* Async's TCP library has a function Tcp.Server.create which allows us to very
* easily create a TCP server. Tcp.Server.create takes in two arguments: the
* internet address on which to listen and a function. When we call create, it
* starts a TCP server. Whenever a client connects to the server, a Reader.t
* and Writer.t are formed from the TCP connection and passed to the function
* we gave to Tcp.Server.create. *)
(* Here, printer is the function we'll pass to Tcp.Server.create. The first
* argument is the address of the client, which we'll rarely use. The second
* and third are the Reader.t and Writer.t of the underlying TCP connection.
* Since we're not going to use the address or writer, we bind them to _, and
* since we are going to use the writer, we bind it to the variable r. *)
let printer _ r _ =
(* In the previous chapter, we saw how to interact with readers and writers
* using files and stdin. Now we're dealing with TCP conncetions, but
* nothing's changed. We read a line from a TCP connection the same way we
* read a line from a file or from stdin! This means we don't have to learn
* anything new in order to be familiar with network programming in OCaml. *)
Reader.read_line r >>| function
| `Eof -> print_endline "error"
| `Ok s -> print_endline s
let main () : unit Deferred.t =
(* In order to launch the server, we first choose the server's port. *)
let port = 8080 in
printf "listening on port %d\n" port;
(* Then, we Tcp.on_port to create a description of the socket the TCP server
* should listen on. *)
let where_to_listen = Tcp.on_port port in
(* Finally, we create the server with Tcp.Server.create. create returns an
* object of type Tcp.Server.t, but we won't use the server, so we ignore it.
*)
ignore (Tcp.Server.create where_to_listen printer);
(* We want our TCP server to run forever, so we return a deferred that never
* becomes determined! *)
never ()
(* Compile and run this program. It should print "listening on port 8080".
* Then, run the following command to connect to the server: `telnet localhost
* 8080`. This will open up an interactive telnet shell that's connected to our
* server. Type in something and hit enter. The server will print out your
* message and then end the connection, forcing your telnet session to
* terminate. *)
let () =
Command.(run (async ~summary:"" Spec.empty main))