【原创】Erlang 的 gen_tcp:send 为什么没有 timeout 选项


在 gen_tcp 文档中有如下说明:

The fact that the send call does not accept a timeout option, is because timeouts on send is handled through the socket option send_timeout. The behavior of a send operation with no receiver is in a very high degree defined by the underlying TCP stack, as well as the network infrastructure. If one wants to write code that handles a hanging receiver that might eventually cause the sender to hang on a send call, one writes code like the following.

大致意思为,sender 发送时没有 receiver 的情况,已经通过底层 TCP 协议栈很好的解决了,如果 sender 想使用带 timeout 功能的 send ,则需要在 connect 的时候指定 {send_timeout, xxx}

假定的使用场景(取自 gen_tcp ):

business process <--> client process(connect) <--> server process(accept)

...
gen_tcp:connect(HostAddress, Port, [{active,false}, {send_timeout, 5000}, {packet,2}]),
loop(Sock),
...

In the loop where requests are handled, we can now detect send timeouts:
loop(Sock) ->
    receive
        %% 这里是来自 business 的消息发送命令
        {Client, send_data, Binary} ->
            case gen_tcp:send(Sock,[Binary]) of
                %% 这里完成针对 send 的超时处理
                {error, timeout} ->
                    io:format("Send timeout, closing!~n", []),
                    %% 可以针对超时做业务处理
                    handle_send_timeout(), % Not implemented here
                    Client ! {self(),{error_sending, timeout}},
                    %% Usually, it's a good idea to give up in case of a 
                    %% send timeout, as you never know how much actually 
                    %% reached the server, maybe only a packet header?!
                    %% 这里建议直接关闭
                    gen_tcp:close(Sock);
                {error, OtherSendError} ->
                    io:format("Some other error on socket (~p), closing",
                              [OtherSendError]),
                    Client ! {self(),{error_sending, OtherSendError}},
                    gen_tcp:close(Sock);
                ok ->
                    Client ! {self(), data_sent},
                    loop(Sock)
            end
    end.

      通常情况下,上述代码足以检测 receive 端的超时问题。大多数协议都会存在某种来自 server 端的确认机制,若存在,则不需要上述代码实现的 send 超时检测。需要使用的唯一场景是应用层协议是单向、无确认机制的情况。

 

转载于:https://my.oschina.net/moooofly/blog/281993

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值