使用ocaml Lwt套接字

时间:2015-08-19 18:25:56

标签: sockets ocaml

我一直在学习Ocaml一周,有些事情变得清晰,其他事情则没有。 我试图组建一个简单的Tic-Tac-Toe服务器,通过telnet接受连接。只是一个字。 我现在必须使用Lwt和rigth,因为我面临着太多的语言因素。 代码的开头:

let sock = Lwt_unix.socket Unix.PF_INET Unix.SOCK_STREAM 0

let setting_up_server_socket =  
    let sockaddr = (Unix.ADDR_INET(Unix.inet_addr_of_string "127.0.0.1", 23233)) in
    Lwt_unix.set_close_on_exec sock;
    Lwt_unix.setsockopt sock Unix.SO_REUSEADDR true;
    Lwt_unix.bind sock sockaddr;
    Lwt_unix.listen sock 20
好的,那很清楚。服务器套接字设置为侦听客户端连接。让我们来试试第一位客人:

let handle_income = 
    Lwt_unix.accept sock;;

似乎很清楚,但是:

val handle_income : (Lwt_unix.file_descr * Lwt_unix.sockaddr) Lwt.t = <abstr>

我在这里堆积。我甚至都不知道如何向客户端套接字发送消息。 与一般的Unix.accept不同,它返回(&#39; a *&#39; b)Lwt.t.一些问题:

  1. 我如何获得纯客户端&#34; Lwt_unix.file_descr&#34;从那?
  2. (&#39; a *&#39; b)Lwt.t.是一个属于Lwt.t对象的元组,不是吗?或者它只是一个领域?我很困惑。
  3. P.S。对不起,如果我的英语不被接受。我很久以前就在学习它。由于问题已经提出,请提供一些建议,我可以在那里获得有关Ocaml的最佳信息。最好的意思是短/清晰度。正好阅读O&#39; REILLY我立即忘记了我在5分钟前阅读的内容,因为它从来都不清楚作者所说的是什么。 Ocaml与我开始使用的Java和JS完全不同。

1 个答案:

答案 0 :(得分:4)

类型'a Lwt.t的值表示一旦准备好就会评估为'a类型值的线程(或错误出错的线程)。从'a获取'a Lwt.t的唯一方法是将其绑定到另一个函数,该函数将在'a Lwt.t线程完成且数据准备就绪后立即调用。您可以使用Lwt.bind函数绑定,也可以使用中缀符号>>=

例如:

let process_client fd = 
  Lwt_unix.accept fd >>= fun (cli,sock) ->
  let chan = Lwt_io.(of_fd ~mode:output cli) in
  Lwt_io.fprintf chan "hi there, and bye!" >>= fun () ->
  Lwt_io.close chan

这使用中缀表示法,您可以将其重写为更详细:

let reply chan = 
  Lwt_io.fprintf chan "hi there, and bye!"

let finish chan = Lwt_io.close chan

let create_chan = Lwt_io.(of_fd ~mode:output cli)

let process_client fd = 
  let accept_t = Lwt_unix.accept fd in
  let chan_t = Lwt.map accept_t create_chan in
  let reply_t = Lwt.bind accept_t reply in 
  Lwt.bind reply_t finish

_t指定thread的位置。即,accept_t是一个最终将返回一对文件描述符和套接字地址的线程。 chan_t是一个返回通道的线程(用于执行缓冲的io)。

Lwt还附带了对特殊语法的支持。实际上支持两种语法,旧的camlp4和更新的ppx。在旧语法中,可以按如下方式编写process_client函数:

let process_client fd = 
  lwt (cli,sock) = Lwt_unix.accept fd in
  let chan = Lwt_io.(of_fd ~mode:output cli) in
  lwt () = Lwt_io.fprintf chan "hi there, and bye!" in
  Lwt_io.close chan

lwtlet的一种特殊形式,不仅可以将名称绑定到值,还可以等待它们进行评估。

我希望我回答你所有的问题。您可能还会发现此library有趣。

P.S。我没有测试代码,所以如果您有任何问题,请不要犹豫。

P.P.S。我留下了一个适当的shutdown程序,以保持代码简单。