原创作者: hideto   阅读:5171次   评论:0条   更新时间:2011-06-01    
1,chat_server.erl
-module(chat_server).
-export([start/1]).

-define(TCP_OPTIONS, [list, {packet, 0}, {active, false}, {reuseaddr, true}]).

start(Port) ->
  Pid = spawn(fun() -> manage_clients([]) end),
  register(client_manager, Pid),
  {ok, LSocket} = gen_tcp:listen(Port, ?TCP_OPTIONS),
  do_accept(LSocket).

do_accept(LSocket) ->
  {ok, Socket} = gen_tcp:accept(LSocket),
  spawn(fun() -> handle_client(Socket) end),
  client_manager ! {connect, Socket},
  do_accept(LSocket).

handle_client(Socket) ->
  case gen_tcp:recv(Socket, 0) of
    {ok, Data} ->
      client_manager ! {data, Data},
      handle_client(Socket);
    {error, closed} ->
      client_manager ! {disconnect, Socket}
  end.

manage_clients(Sockets) ->
  receive
    {connect, Socket} ->
      io:fwrite("Socket connected: ~w~n", [Socket]),
      NewSockets = [Socket | Sockets];
    {disconnect, Socket} ->
      io:fwrite("Socket disconnected: ~w~n", [Socket]),
      NewSockets = lists:delete(Socket, Sockets);
    {data, Data} ->
      send_data(Sockets, Data),
      NewSockets = Sockets
  end,
  manage_clients(NewSockets).

send_data(Sockets, Data) ->
  SendData = fun(Socket) ->
    gen_tcp:send(Socket, Data)
  end,
  lists:foreach(SendData, Sockets).

server监听Socket连接,并群发消息到所有的client

2,chat_send_client.erl
-module(chat_send_client).
-export([start/2]).

start(IP, Port) ->
  {ok, Socket} = gen_tcp:connect(IP, Port, [binary, {packet, 4}]),
  talk(Socket).

talk(Socket) ->
  Msg = io:get_line('Input you msg:'),
  ok = gen_tcp:send(Socket, term_to_binary(Msg)),
  talk(Socket).

send_client用来启动一个client发消息的进程

3,chat_recv_client.erl
-module(chat_recv_client).
-export([start/2]).

start(IP, Port) ->
  {ok, Socket} = gen_tcp:connect(IP, Port, [binary, {packet, 4}]),
  recv_msg(Socket).

recv_msg(Socket) ->
  receive
    {tcp, Socket, Bin} ->
      Msg = binary_to_term(Bin),
      io:format("Received msg: ~p~n", [Msg]),
      recv_msg(Socket)
  end.

recv_client用来在client端实时显示所有登录聊天室的client发送的消息

4,启动server
Eshell> chat_server:start(9999).


5,启动send和recv两个client进程
$$ client1
Eshell> chat_send_client:start("localhost", 9999).
Eshell> chat_recv_client:start("localhost", 9999).
$$ client2
Eshell> chat_send_client:start("localhost", 9999).
Eshell> chat_recv_client:start("localhost", 9999).



6,交互过程
%% client1/send
Input you msg:我囧
%% client2/send
Input you msg:你囧啥?
%% client1、2/recv
Received msg: "我囧\n"
Received msg: "你囧啥?\n"
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

文章信息

Global site tag (gtag.js) - Google Analytics