Hi,
I just picked up OCaml and been playing around with the Async TCP module. I’m trying to build a server/client that chat with each other over a TCP connection. (Similar to the behavior of netcat when you open client and server)
This is the function that starts the server, listening on port p.
let start_server p =
let host_and_port =
Tcp.Server.create
~on_handler_error:`Raise
(Tcp.Where_to_listen.of_port p)
(fun sock reader writer ->
conn_handler sock reader writer)
in
ignore (host_and_port : (Socket.Address.Inet.t, int) Tcp.Server.t Deferred.t);
Deferred.never ()
This is the function that starts the client, connecting to an address, a and port p.
let start_client a p =
Tcp.with_connection
(Tcp.Where_to_connect.of_host_and_port { host = a; port = p})
(fun sock reader writer ->
conn_handler sock reader writer)
As you can see from the code snippets, both call the function, conn_handler after server is started/client is connected.
My logic behind conn_handler: client/server has to simultaneously:
- Read from stdin and write to the socket using w,
- Read from r, print to stdout and write to the socket “Acknowledged”.
Current implementation of conn_handler:
let rec conn_handler s r w =`
let stdin = Lazy.force Reader.stdin in
Reader.read_line stdin >>= function
| `Eof -> return ()
| `Ok x ->
Writer.write_line w x;
Reader.read_line r >>= function
| `Eof -> return ()
| `Ok "exit" -> return ()
| `Ok x ->
print_endline x;
Writer.write_line w "Acknowledged";
conn_handler s r w
This implementation allows both client & server to send message to each other, but the behavior is buggy, probably have to do with the logic behind when Deferreds are determined.
Is my logic wrong? Should I implement separate connection handler functions for server and client?
If not, how do i modify the above conn_handler to achieve (1) and (2) simultaneously?