3

この方法でクライアントとの接続を確立しました。

gen_tcp:listen(1234,[binary,{packet,0},{reuseaddr,true},{active,false},{recbuf,2048}]).

このコードは、メッセージ処理を実行します。

loop(Socket)->
    inet:setops(Socket,[{active,once}],
    receive
        {tcp,Socket,Data}->
            handle(Data),
            loop(Socket);
        {Pid,Cmd}->
            gen_tcp:send(Socket,Cmd),
            loop(Socket);
        {tcp_close,Socket}->
            % ...
end.

私のOSはWindowsです。メッセージのサイズが 1024 バイトの場合、 でバイトが失われますData。サーバーは ACK + FIN をクライアントに送信します。

Erlang は 1024 バイトに制限されていると思われるため、 を定義しrecbufました。

問題の場所: Erlang、Windows、ハードウェア?

ありがとう。

4

1 に答える 1

2

受信バッファの設定が小さすぎる可能性があります。Erlang は確かに 1024 バイトのバッファーに制限されていません。シェルで次のように実行して、自分で確認できます。

{ok, S} = gen_tcp:connect("www.google.com", 80, [{active,false}]),
O = inet:getopts(S, [recbuf]),
gen_tcp:close(S),
O.

Mac OS XI では、約 512Kb のデフォルトの受信バッファ サイズを取得します。


解析すると{packet, 0}、ネットワークスタックが送信することを選択したチャンクでtcpデータを受信するため、メッセージ境界の解析とバッファリングを自分で行う必要があります。ワイヤ プロトコルでメッセージの境界を確認する信頼できる方法はありますか? その場合は、tcp データを受信し、完全なメッセージが得られるまでバッファ変数に追加します。次に、完全なメッセージに対してハンドルを呼び出し、続行する前に完全なメッセージをバッファーから削除します。

クライアントと使用中のプロトコルに関する情報を提供していただければ、おそらくもっと役立つでしょう。

于 2011-02-19T01:58:53.807 に答える