Я хотел попробовать модуль Lwt_unix
для простого клиента, который читает данные в сокете до тех пор, пока читать нечего. Некоторые сказали мне, что Lwt
создает неблокирующие сокеты, но с моим кодом он все еще блокируется:
open Lwt
open Unix
(* ocamlfind ocamlc -o lwt_socket_client -package lwt,lwt.unix,unix -linkpkg -g lwt_socket_client.ml *)
let host = Unix.inet_addr_loopback
let port = 6600
let create_socket () =
let sock = Lwt_unix.socket PF_INET SOCK_STREAM 0 in
Lwt_unix.set_blocking sock false;
sock
let s_read sock maxlen =
let str = Bytes.create maxlen in
let rec _read sock acc =
Lwt.ignore_result(Lwt_io.write_line Lwt_io.stdout "_read");
Lwt_unix.read sock str 0 maxlen >>= fun recvlen ->
Lwt.ignore_result(Lwt_io.write_line Lwt_io.stdout (string_of_int recvlen));
if recvlen = 0 then Lwt.return (acc)
else _read sock (acc ^ (String.sub str 0 recvlen))
in _read sock ""
let socket_read sock =
Lwt.ignore_result(Lwt_unix.connect sock @@ ADDR_INET(host, port));
s_read sock 1024 >>= fun answer ->
Lwt_io.write_line Lwt_io.stdout answer
let () =
let sock = create_socket () in
Lwt_main.run (socket_read sock)
Если я попробую этот пример с термином:
echo "totoche" | netcat -l 127.0.0.1 -p 6600
тогда результат:
./lwt_socket_client
_read
8
_read
Какой блок, пока я не нажму Ctrl+c.
Я пробовал оба с:
Lwt_unix.set_blocking sock false;
и
Lwt_unix.set_blocking sock true;
и конечно без этой строки, но все равно блокирует. Что я делаю не так?
Для получения дополнительной информации, один из моих предыдущих вопросов: неблокирующий клиентский сокет OCaml
ignore_result x; ...
означает, что это нужно делать в фоновом режиме, не дожидаясь этого. Вероятно, вы хотитеx >>= fun () -> ...
(подождите, пока x завершится, затем...) - person Thomas Leonard   schedule 25.09.2016