1

こんにちは、私はこのような状況にあります:

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

を使用gen_tcp:recv(Sock,0)しますが、サーバーからのメッセージには特定の終了パターンがないため、recv でクライアントがブロックされないようにする方法はありますか?

ドキュメントから:

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.
4

1 に答える 1

4

まず第一に、メッセージが終了したことを知らないプロトコルを使用するのは得策ではありません。したがって、プロトコルを制御できる場合は、プロトコル メッセージの前にメッセージ長などを追加することをお勧めします。

とはいえ、受信時にブロックしない方が望ましい場合もよくあります。

その間、他のプロセスからのメッセージを処理するために後で到着する可能性のあるデータを待つ間、ブロックを防ぎたいと思います。

これに対する解決策は、ソケット オプションを使用すること{active, once}です。

ここでErlangソケットオプションの説明を参照してください:

値が 1 回 ( {active, once}) の場合、ソケットからの 1 つのデータ メッセージがプロセスに送信されます。もう 1 つのメッセージを受信setopts/2するには、オプションを指定して再度呼び出す必要があり{active, once}ます。

{active, true}すべてのデータのメッセージを使用して取得したくなるかもしれません。これに関する問題は、フロー制御がないことです。そのため、データが殺到すると、すべてが VM によってすぐに読み取られ、メッセージ メールボックスに詰め込まれます。メールボックスが大きくなると速度が低下し、すべてのメモリを消費する可能性があるため、これはすぐに手に負えなくなります。

を使用すると{active, once}、このメッセージの氾濫を回避できます。

これについては、 Learn You Some Erlang: More Control With Inetにも説明があります。

于 2012-08-18T10:32:26.600 に答える