[erlang-questions] Problems with sending UDP datagrams without buffering

Matthias Lang <>
Thu Oct 30 19:51:10 CET 2008


On Thursday, October 30, mats cronqvist wrote:

>   possibly relevant? from the inet:setopts doc;
> 
> {delay_send, Boolean} 

No, for several reasons. Firstly, the original poster didn't say
anything about using nondefault options, and nobody would ever be so
careless as to post a bug report without fully disclosing what they're
doing. Secondly, if this option does anything at all for UDP, it still
shouldn't merge successive UDP datagrams.

But, let's look at the source:

  inet:setopts(S, [{delay_send, true}]) 
    calls prim_inet:setopts(S, [{delay_send, true}]
      calls ctl_cmd(S, ?INET_REQ_SETOPTS, encode_opt_val([{delay_send, true}))

encode_opt_value() takes a bit of unravelling, but it eventually
encodes delay_send as ?INET_LOPT_TCP_DELAY_SEND. Note the "TCP" in
there.

Finally ctl_cmd calls erlang:port_control(S, ?INET_REQ_SETOPTS, [?INET_LOPT_TCP_DELAY_SEND, ...])

At that point, we need to go and look at the TCP driver, inet_drv.c. 
And there we find this code:

        case INET_LOPT_TCP_DELAY_SEND:
            if (desc->stype == SOCK_STREAM) {
                tcp_descriptor* tdesc = (tcp_descriptor*) desc;
                if (ival)
                    tdesc->tcp_add_flags |= TCP_ADDF_DELAY_SEND;
                else
                    tdesc->tcp_add_flags &= ~TCP_ADDF_DELAY_SEND;
            }
            continue;

For a UDP socket, the desc->stype is SOCK_DGRAM, so this does nothing.

Conclusion: {delay_send, true} is a no-op for UDP sockets and thus
not relevant to the original poster's question.

Since both you and Johnny had doubts about this, I'd like to second
Johnny's suggestion of making the man page dispel that possibility.
I've appended a suggested new version below.

Matthias

----------------------------------------------------------------------


{delay_send, Boolean}

    Default is false.

    Does not apply to UDP sockets. Corresponds to the tcp(7) TCP_NODELAY
    option. 

    Normally, when an Erlang process sends to a socket, the driver
    will try to immediately send the data. If that fails, the driver
    will use any means available to queue up the message to be sent
    whenever the operating system says it can handle it. Setting
    {delay_send, true} will make all messages queue up. This makes the
    messages actually sent onto the network be larger but fewer. The
    option actually affects the scheduling of send requests versus
    Erlang processes instead of changing any real property of the
    socket. This is an implementation specific option.



More information about the erlang-questions mailing list