Hatena::Grouperlang

Erlang Mind

 | 

2009-01-03

動きました。

| 05:04

たいしたことやってません。基本は gen_tcp の example です。それに gen_tcp:controlling_process を使って accept で生成したソケットを別プロセスに渡しています。

これの問題は無限のプロセスを生成してしまうことでしょうか。 connect に after でタイムアウト処理を付ければ上手くいくのかな。

基本の基で突っかかってるあたり未熟だなぁと実感させられました。

-module(tcp_echo_server).
-compile(export_all).

-define(kOptions, [{active, false}, binary, {packet, 2}]).
-define(kMaxAcceptors, 5).

start() ->
  case gen_tcp:listen(5000, ?kOptions) of
    {ok, ListenSocket} ->
      start_acceptors(?kMaxAcceptors, ListenSocket),
      {ok, Port} = inet:port(ListenSocket),
      Port;
    {error, _Reason} ->
      error
  end.

start_acceptors(0, _) ->
  ok;
start_acceptors(Num, ListenSocket) ->
  Pid = spawn(fun() -> acceptor(ListenSocket) end),
  io:format("acceptor: ~p:~p\n", [Num, Pid]),
  start_acceptors(Num-1, ListenSocket).

acceptor(ListenSocket) ->
  case gen_tcp:accept(ListenSocket) of
    {ok, Socket} ->
      io:format("accept: ~p\n", [self()]),
      Pid = spawn(fun() -> connect(Socket) end),
      gen_tcp:controlling_process(Socket, Pid),
      acceptor(ListenSocket);
    {error, _Reason} ->
      acceptor(ListenSocket)
  end.

connect(Socket) ->
  inet:setopts(Socket, [{active, once}]),
  receive
    {tcp, Socket, Packet} ->
      io:format("tcp: ~p\n", [Packet]),
      gen_tcp:send(Socket, Packet),
      connect(Socket);
    {tcp_closed, Socket} ->
      io:format("tcp_closed: ~p\n", [self()]),
      ok = gen_tcp:close(Socket);
    {tcp_error, Socket, _Reason} ->
      io:format("tcp_error: ~p\n", [self()]),
      ok = gen_tcp:close(Socket)
  end.

くらいあんと(コピペだけど)

-module(client).
-compile(export_all).

-define(kOptions, [{active,false}, binary, {packet,2}]).

client(Message) ->
  {ok, Sock} = gen_tcp:connect("localhost", 5000, ?kOptions),
  gen_tcp:send(Sock,Message),
  A = gen_tcp:recv(Sock, 0),
  gen_tcp:close(Sock),
  A.

jj1bdxjj1bdx2009/01/03 23:36CPU使用率が100%(=コア1つ分)にすぐ行ってしまうのは,join()で回ってるからなんでしょうか.ここは別の方法で待たせたほうがいいかも.

jj1bdxjj1bdx2009/01/03 23:45{active, false} のときは gen_tcp:recv/2 あるいは gen_tcp:recv/3 を使えとありますね.
http://www.erlang.org/doc/man/gen_tcp.html
acceptの項の最後を参照

VoluntasVoluntas2009/01/04 03:18join() は wait かけるための最低の手です ... orz ここも見直してみます。
{active, true} のときは recv ... 未熟でした。もう一度そこを読んでみます。

jj1bdxjj1bdx2009/01/04 08:37client:client/1 の gen_tcp:connect/3の3番目の引数には ? が必要ですね(マクロだから).

VoluntasVoluntas2009/01/04 16:42おぉ、抜けてました。ご指摘ありがとうございます。修正しておきました:-)

CassaraCassara2012/10/08 20:54Holy Toledo, so glad I clckied on this site first!

bkmordobkmordo2012/10/09 05:574tZvuJ <a href="http://zehjwmjpcoki.com/">zehjwmjpcoki</a>

yyycuvdnzyyycuvdnz2012/10/10 07:58xCiddm , [url=http://gzmhquslkjha.com/]gzmhquslkjha[/url], [link=http://nmaogmzlhulx.com/]nmaogmzlhulx[/link], http://mqlpicqhechk.com/

drdnderdrdnder2012/10/11 14:08c9XYnu <a href="http://juegccmxktvp.com/">juegccmxktvp</a>

rfncomxvjrfncomxvj2012/10/12 03:31UsbXzD , [url=http://dqgeiymejisp.com/]dqgeiymejisp[/url], [link=http://ihahrqezdfnx.com/]ihahrqezdfnx[/link], http://ckvytfbhohkb.com/

 |