请教一个socket下半阻塞模式的疑问

43 views
Skip to first unread message

Yupei

unread,
Mar 14, 2012, 1:49:40 AM3/14/12
to erlang...@googlegroups.com
        {active,once}为半阻塞。我能理解它先是收一条非阻塞数据,然后阻塞掉客户端。

        但对于书上有一句 “在程序处于被动模式的时候,我们只能等待一个套接字的数据,这在必须同时等待多个套接字的数据的程序时,就显得无能为力了”

        我的问题是,半阻塞模式,跟<同时等待多个套接字>这个应用场景有什么关系呢?即使在阻塞模式下,要等待多个套接字数据,无非就是每accept一次,spawn一个进程出来gen_tcp:recv 就行了。 另外还有流量控制,阻塞模式为什么不能用来控制流量呢?不也要等主动gen_tcp:recv时才取数据,否则发送端是被阻塞住的。

        请各位指点。

Wei Cao

unread,
Mar 15, 2012, 4:15:09 AM3/15/12
to erlang...@googlegroups.com
书上的意思是这样,如果在同一个erlang进程中,同时等待多个socket上的数据,那么用passive mode就只能等到一个socket上的数据到了,才能接收其他socket上发来的数据。
和你描述的情景“每accept一次,spawn一个进程出来gen_tcp:recv“不一样。

事实上,用一个进程来处理一个socket,passive mode和active once没多大差别,因为passive mode的实现是
向inet driver发recv命令出去,然后阻塞在那里等待接收一条{inet_async, S, Ref, Status}消息。

在inet_driver中,收到消息时,如果socket是处在passive mode的,就会向caller发回一条消息inet_async消息,否则就调tcp_message发回一条active mode message {tcp, S, [H1,...Hsz | Data]}。
tcp_reply_data()

        /* No body parsing, return raw binary */
        if (desc->inet.active == INET_PASSIVE)
            return inet_async_data(INETP(desc), body, bodylen);
        else
            code = tcp_message(INETP(desc), body, bodylen);
    }

    if (code < 0)
    return code;
    if (desc->inet.active == INET_ONCE)
    desc->inet.active = INET_PASSIVE;

如果是active once模式,发完一条消息就变成passive mode了。
--

Best,

Wei Cao

Yupei

unread,
Mar 15, 2012, 9:54:52 PM3/15/12
to erlang...@googlegroups.com
感谢答疑,这下开朗了~ 原来是指"同一进程处理多个socket“这种场景下。忽略了这个前提,纠结了老久不得其解。

再次感谢。

ps:这个邮件组最近好冷清啊。。。

Feng Yu

unread,
Mar 16, 2012, 2:56:04 AM3/16/12
to erlang...@googlegroups.com
多问问题就热闹了。
专注高性能容错分布式服务器的研究和实现
http://blog.yufeng.info


2012/3/16 Yupei <syu...@gmail.com>

蓝上皓

unread,
Mar 16, 2012, 3:41:09 AM3/16/12
to erlang...@googlegroups.com
erlang第一人!!!围观

Falood Hao

unread,
Mar 17, 2012, 6:29:03 AM3/17/12
to erlang...@googlegroups.com
BOSS 级人物出现了呀~围观 +1

2012/3/16 蓝上皓 <lansh...@gmail.com>

Bob

unread,
Mar 18, 2012, 8:58:54 PM3/18/12
to erlang...@googlegroups.com
书上的意思是这样,如果在同一个erlang进程中,同时等待多个socket上的数据,那么用passive mode就只能等到一个socket上的数据到了,才能接收其他socket上发来的数据。
请问,该erlang进程会等待哪个socket数据到了,才接受其它socket数据呢?会默认获取最先数据达到得socket吗? 



-- 
Bob

Reply all
Reply to author
Forward
0 new messages