Erlang实现简单聊天室

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”

猜你喜欢

转载自blog.csdn.net/qq_21743659/article/details/108508753