# Async socket question

**URL:** <https://discuss.ocaml.org/t/async-socket-question/4838>\
**Category:** Community\
**Tags:** async\
**Created:** [December 9, 2019, 5:07pm UTC](https://discuss.ocaml.org/t/async-socket-question/4838 "2019-12-09T17:07:48Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![msbic](https://avatars.discourse-cdn.com/v4/letter/m/ce7236/32.png) [@msbic](https://discuss.ocaml.org/u/msbic)\
**Post date:** [December 9, 2019, 5:07pm UTC](https://discuss.ocaml.org/t/async-socket-question/4838/1 "2019-12-09T17:07:48Z")

</div>

Hi all. This is my first post, and I am quite new to OCaml.

I am working on a small TCP client utility, using Async/Core.

The connection is opened using

`Tcp.with_connection (Tcp.Where_to_connect.of_host_and_port { host = "localhost"; port = myPort })`

I need to be able to accept keyboard input, as well as read input from the socket. I use the Deferred.any for this purpose.

Calling `Reader.read reader buf` on the socket results in `Eof, which is OK, but when the method (containing the Deferred.any code) is called recursively, I get an exception:

“unhandled exception in Async scheduler”  
(“unhandled exception”  
((monitor.ml.Error  
(“can not read from reader” (reason “in use”)  
(reader  
((id 0) (state In\_use) (available 0) (pos 0)  
(open\_flags (Full (Ok (rdwr () (unrecognized\_bits 0x8000)))))  
(last\_read\_time (2019-12-09 11:34:02.122535-05:00))  
(close\_may\_destroy\_buf Not\_now) (close\_finished Empty)  
(fd  
((file\_descr 0) (info ) (kind Char) (supports\_nonblock false)  
(have\_set\_nonblock false) (state (Open Empty))  
(watching ((read Not\_watching) (write Not\_watching)))  
(watching\_has\_changed false) (num\_active\_syscalls 1)  
(close\_finished Empty))))))

Reader.is\_closed on the reader returns false.  
How can I “monitor” the socket recursively without this exception?

Michael

---

<div class="post-metadata">

**Author:** ![bcc32](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/bcc32/32/203_2.png) [@bcc32](https://discuss.ocaml.org/u/bcc32)\
**Post date:** [December 9, 2019, 7:16pm UTC](https://discuss.ocaml.org/t/async-socket-question/4838/2 "2019-12-09T19:16:12Z")

</div>

> [@msbic](#):
>
> but when the method (containing the Deferred.any code) is called recursively, I get an exception:

It’s a bit difficult to know what you mean by this. Can you share the code you are using to try to read from the socket?

---

<div class="post-metadata">

**Author:** ![msbic](https://avatars.discourse-cdn.com/v4/letter/m/ce7236/32.png) [@msbic](https://discuss.ocaml.org/u/msbic)\
**Post date:** [December 9, 2019, 7:43pm UTC](https://discuss.ocaml.org/t/async-socket-question/4838/3 "2019-12-09T19:43:35Z")

</div>

```
let logIn reader writer _ = 
  let buf = Bytes.create 1024 in
  Writer.write writer ( generateLogonMessage 1 );
  Writer.flushed writer >>= function () -> 
  Reader.read reader buf >>| function
    | `Eof -> None 
    | `Ok len -> Some (buf)
    

let readInput reader =      
   let buf = Bytes.create 2048 in 
    Deferred.any [ 
      (Reader.read_line inn >>= function
      | `Eof -> return None
      | `Ok line -> return (Some (Bytes.of_string line))); (* user input *)
      
      (Reader.read reader buf >>= function
      | `Eof -> return None
      | `Ok len -> return (Some (Bytes.sub ~pos:0 ~len:len buf))); (* data from server *) ]
  

let onConnect _ reader writer =
  let rec loop connected =
      let seqNum = 0 in
      match connected with
      | false -> logIn reader writer (seqNum + 1) >>= (function 
                | None -> (loop true)
                | Some _ -> (loop false))
      | true -> 
            
        readInput reader >>= function 
          | None -> (loop true)
          | Some command -> begin
            
            match (String.substr_index command ~pattern:"cmd:") with
            | None -> Writer.write out command; Writer.flushed out 
            | Some _ -> Writer.write_bytes writer command; Writer.flushed writer 

            end           
          in (loop false)
```

---

<div class="post-metadata">

**Author:** ![msbic](https://avatars.discourse-cdn.com/v4/letter/m/ce7236/32.png) [@msbic](https://discuss.ocaml.org/u/msbic)\
**Post date:** [December 9, 2019, 7:44pm UTC](https://discuss.ocaml.org/t/async-socket-question/4838/4 "2019-12-09T19:44:41Z")

</div>

readInput is supposed to take input from keyboard/socket

---

<div class="post-metadata">

**Author:** ![bcc32](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/bcc32/32/203_2.png) [@bcc32](https://discuss.ocaml.org/u/bcc32)\
**Post date:** [December 9, 2019, 9:03pm UTC](https://discuss.ocaml.org/t/async-socket-question/4838/5 "2019-12-09T21:03:53Z")

</div>

Ah, I believe what is happening is that you have two simultaneous calls to `Reader.read`, which is disallowed (see the module comment on `Reader`):

> Each of the read functions returns a deferred that will become determined when the read completes. It is an error to have two simultaneous reads. That is, if you call a read function, you should not call another read function until the first one completes.

One suggestion would be to use the `Pipe` interface rather than directly using `Reader`. You can call `Reader.lines` or `Reader.pipe` and then use `Pipe.read_choice` to “try” to read from the socket (without actually consuming the data if the other input arrives first).

---

<div class="post-metadata">

**Author:** ![msbic](https://avatars.discourse-cdn.com/v4/letter/m/ce7236/32.png) [@msbic](https://discuss.ocaml.org/u/msbic)\
**Post date:** [December 9, 2019, 9:46pm UTC](https://discuss.ocaml.org/t/async-socket-question/4838/6 "2019-12-09T21:46:12Z")

</div>

So, it is not possible to read from 2 different sources simultaneously?

---

<div class="post-metadata">

**Author:** ![bcc32](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/bcc32/32/203_2.png) [@bcc32](https://discuss.ocaml.org/u/bcc32)\
**Post date:** [December 9, 2019, 10:11pm UTC](https://discuss.ocaml.org/t/async-socket-question/4838/7 "2019-12-09T22:11:21Z")

</div>

You can read from two **different** sources simultaneously. Rather, you cannot call `Reader.read` on the **same** `Reader.t` twice simultaneously.

What I think is happening is that on the first call to `loop`, you read from user input and also the socket. One of them completes, which causes `loop` to be called again. But it calls `Reader.read` again, on the same two `Reader.t`'s. If the one which was waiting for input in the first call is still waiting for input, then you have called `Reader.read` twice simultaneously on the same `Reader.t`, which is disallowed. (There is also a correctness bug, because you will throw away the data that you consumed from the first call to `Reader.read` on the slower input).

Instead, you can do something like:

```ocaml
let readInput in1 in2 =
  Deferred.choice
    [Pipe.read_choice_single_consumer_exn in1 [%here] |> Deferred.Choice.map ~f:Either.first
    ; Pipe.read_choice_single_consumer_exn in2 [%here] |> Deferred.Choice.map ~f:Either.second
    ]
  >>= function
  | First input_from_in1 -> do_something ()
  | Second input_from_in2 -> do_something_else ()

```

You can get `Pipe.Reader.t`'s from the `Reader.t` using `Reader.pipe` (call once and reuse the same `Pipe.Reader.t`).

---

<div class="post-metadata">

**Author:** ![msbic](https://avatars.discourse-cdn.com/v4/letter/m/ce7236/32.png) [@msbic](https://discuss.ocaml.org/u/msbic)\
**Post date:** [December 10, 2019, 2:59pm UTC](https://discuss.ocaml.org/t/async-socket-question/4838/8 "2019-12-10T14:59:29Z")

</div>

Thanks a lot!  
I really like working with OCaml, but it’s hard to come across code examples, especially for advanced topics such as this.
