# Simple chat with Async.Tcp module

**URL:** <https://discuss.ocaml.org/t/simple-chat-with-async-tcp-module/4946>\
**Category:** Learning\
**Tags:** async\
**Created:** [January 2, 2020, 8:57am UTC](https://discuss.ocaml.org/t/simple-chat-with-async-tcp-module/4946 "2020-01-02T08:57:49Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![chwee](https://avatars.discourse-cdn.com/v4/letter/c/73ab20/32.png) [@chwee](https://discuss.ocaml.org/u/chwee)\
**Post date:** [January 2, 2020, 8:57am UTC](https://discuss.ocaml.org/t/simple-chat-with-async-tcp-module/4946/1 "2020-01-02T08:57:49Z")

</div>

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** :

1. Read from stdin and write to the socket using _w_,
2. 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?

---

<div class="post-metadata">

**Author:** ![mbacarella](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mbacarella/32/2420_2.png) [@mbacarella](https://discuss.ocaml.org/u/mbacarella)\
**Post date:** [January 3, 2020, 3:54pm UTC](https://discuss.ocaml.org/t/simple-chat-with-async-tcp-module/4946/2 "2020-01-03T15:54:05Z")

</div>

I assume by buggy you mean your `conn_handler`, as written, isn’t reading from the socket until after you’ve read from stdin.

That’s because you’re specifically sequencing, with the `>>=` operator, for the read from socket to happen after the read from stdin.

If you want to watch both stdin and the reader at the same time and react to either, you can try `Deferred.choose`. See this recent thread [Beginner async question](https://discuss.ocaml.org/t/beginner-async-question/4911/4)

---

<div class="post-metadata">

**Author:** ![mbacarella](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mbacarella/32/2420_2.png) [@mbacarella](https://discuss.ocaml.org/u/mbacarella)\
**Post date:** [January 6, 2020, 4:00pm UTC](https://discuss.ocaml.org/t/simple-chat-with-async-tcp-module/4946/3 "2020-01-06T16:00:31Z")

</div>

For the sake of future generations, I thought I’d mention that the poster seems to have dual asked this question on r/ocaml and received a more detailed answer. [https://www.reddit.com/r/ocaml/comments/ej1niq/help\_with\_writing\_a\_tcp\_server\_with\_async/](https://www.reddit.com/r/ocaml/comments/ej1niq/help_with_writing_a_tcp_server_with_async/)
