Erlang基于Socket实现简单聊天室

1,chat_server.erl
[code]
-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).
[/code]
server监听Socket连接,并群发消息到所有的client

2,chat_send_client.erl
[code]
-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).
[/code]
send_client用来启动一个client发消息的进程

3,chat_recv_client.erl
[code]
-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.
[/code]
recv_client用来在client端实时显示所有登录聊天室的client发送的消息

4,启动server
[code]
Eshell> chat_server:start(9999).
[/code]

5,启动send和recv两个client进程
[code]
$$ 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).

[/code]

6,交互过程
[code]
%% client1/send
Input you msg:我囧
%% client2/send
Input you msg:你囧啥?
%% client1、2/recv
Received msg: "我囧\n"
Received msg: "你囧啥?\n"
[/code]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值