问题描述
我已经学习Ocaml了一个星期,有些事情变得很清楚,而另一些却没有.我试图组成一个简单的井字游戏服务器,它通过telnet接受连接.一句话.我现在必须使用Lwt和rigth,对我来说似乎是个黑暗的地方,因为我面对太多的语言特殊性.代码的开头:
I have been on learning Ocaml for a week, some things got clear, the others rather not.I'm trying to compose a simple Tic-Tac-Toe server accepting connections via telnet. Just for a word.I have to use Lwt and rigth now it seems for me a darken place because I had faced too much of language pecularities.The begining of the code:
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
好的,很明显.服务器套接字设置为侦听客户端连接.让我们尝试第一个客人:
OK, that's clear. The server socket is set to listen for clients connections. Let's try to get a first guest:
let handle_income =
Lwt_unix.accept sock;;
似乎很清楚,但是:
val handle_income : (Lwt_unix.file_descr * Lwt_unix.sockaddr) Lwt.t = <abstr>
在这里我被堆积了.我什至不知道如何向客户端套接字发送消息.与一般的Unix.accept不同,它返回('a *'b)Lwt.t.一些问题:
Here I'm stacked. I don't know even how to send a message to client socket.Unlike general Unix.accept it returns ('a * 'b) Lwt.t. Some questions:
- 如何从中获取纯客户端"Lwt_unix.file_descr"?
- ('a *'b)Lwt.t.是属于Lwt.t对象的元组,不是吗?还是仅仅是一个领域?我很困惑.
P.S.对不起,如果我的英语不能接受.我很久以前就学习了.由于问题已经被提出,请提供一些建议,在这里我可以获取有关Ocaml的最佳信息.最好是平均空头/净空.由于阅读了O'REILLY,我立即忘记了5分钟前的阅读内容,因为目前尚不清楚作者所说的内容或目的是什么. Ocaml与我刚开始使用的Java和JS完全不同.
P.S. Sorry if my English is not acceptable. I was learning it long time ago. As the question is already asked please give a piece of advise, where I can get the best information about Ocaml. The best a mean short/clearness. Due reading O'REILLY I instantly forget what I was reading 5 min ago because it's never clear what this or that the author talking about is used for. Ocaml is quite different with Java and JS I had started with.
推荐答案
类型为'a Lwt.t
的值表示一个线程,一旦准备就绪,该值将评估为类型为'a
的值(否则会出错)错误的).从'a Lwt.t
获取'a
的唯一方法是将其绑定到另一个函数,该函数将在'a Lwt.t
线程完成并且数据准备就绪后立即被调用.您可以使用Lwt.bind
函数进行绑定,该函数也可以使用前缀表示法>>=
来提供.
A value of type 'a Lwt.t
represents a thread that will evaluate to a value of type 'a
once it is ready (or to an error is something went wrong). The only way to get 'a
from 'a Lwt.t
is to bind it to another function, that will be called as soon, as 'a Lwt.t
thread is finished and data is ready. You can bind with Lwt.bind
function, also available in an infix notation >>=
.
例如:
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
这使用了前缀表示法,您可以将其更详细地重写:
This uses infix notation, you can rewrite it more verbose:
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).
Where _t
designates thread
. I.e., accept_t
is a thread that will eventually return a pair of a file descriptor and a socket address. chan_t
is a thread that will return a channel (for doing buffered io).
Lwt
还支持特殊语法.实际上,它支持两种语法,旧的使用camlp4,新的使用ppx.用旧的语法,可以编写process_client
函数,如下所示:
Lwt
also comes with a support for special syntax. Actually with support for two syntaxes, the old with camlp4 and a newer one with ppx. In old syntax, one can write the process_client
function as follows:
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
lwt
是let
的一种特殊形式,它不仅将名称绑定到值,还等待它们求值.
There lwt
is a special form of let
that not only binds names to values, but also waits for them to evaluate.
我希望我回答了你所有的问题.您可能还会发现库有趣.
I hope that I answered all your questions. You may also find this library interesting.
P.S.我没有测试代码,因此,如果您有任何问题,请随时询问.
P.S. I didn't test the code, so if you have any issues, don't hesitate to ask.
P.P.S.我留下了适当的shutdown
过程,以保持代码简单.
P.P.S. I left a proper shutdown
procedure, to keep code simple.
这篇关于使用ocaml Lwt套接字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!