1

Hi I have this situation:

gen_tcp:connect(Address, Port, [{buffer, 1024},{active, false},{packet,0},{send_timeout, infinity}]).

and I use gen_tcp:recv(Sock,0), but the message from the server don't have a particular end pattern, so there's any way to prevent client blocks on recv?

From doc:

do_recv(Sock, Bs) ->
    case gen_tcp:recv(Sock, 0) of
        {ok, B} ->
            do_recv(Sock, [Bs, B]);
        {error, closed} ->
            {ok, list_to_binary(Bs)}
    end.

1 Answers1

4

First of all: it is not a good idea to have a protocol which prevents you from knowing a message ended. So if you have control over the protocol it would be a good idea to have e.g. a message length prepended to your protocol messages.

This said, it is still often preferable not to block on receiving.

I suppose you want to prevent blocking while you wait for more data that might arrive later to handle messages from other processes in the meantime.

The solution to this is to use the socket option {active, once}:

see description of Erlang socket opts here:

If the value is once ({active, once}), one data message from the socket will be sent to the process. To receive one more message, setopts/2 must be called again with the {active, once} option.

You might me tempted to use {active, true} and just get messages for every data. The problem with this is that you have no flow control, so if you get flooded by data everything is read immediately by The VM and stuffed into your message mailbox. This quickly gets out of hand since a growing mailbox slows you down and will possibl eat all your memory.

Using {active, once} avoids this message flooding.

A nice description of this can also be found Learn You Some Erlang: More Control With Inet

Peer Stritzinger
  • 8,232
  • 2
  • 30
  • 43
  • Thanks Peer, and what should i use instead of recv for save the reply? In the example they use flush() but i cannot save message from there, or not? – user1524704 Aug 18 '12 at 13:05
  • 1
    If you did not encounter the "receive" statement and how Erlang messages work by now, you got way ahead of yourself. Best start "Learn You Some Erlang" from the beginning. If you skip the "easy" parts you'll have a hard time using Erlang. Message sending and receiving together with the pattern matching are very important to use Erlang – Peer Stritzinger Aug 18 '12 at 18:22