Erlang之简便聊天室

my_tcp.erl

-module(my_tcp).
-compile(export_all).

start_server() ->
	ets:new(my_ets,[ordered_set, public, named_table, {write_concurrency, true}, {read_concurrency, true}]),%初始化一个表
	case gen_tcp:listen(1234, [binary, {packet,0}, {active,true}]) of
		{ok, ListenSocket} ->
			spawn(fun() -> wait_a_client(ListenSocket) end);
		{error, Msg} ->
			io:format("~p~n",[Msg])
	end.

wait_a_client(ListenSocket) ->
		case gen_tcp:accept(ListenSocket) of%等待一个连接
		{ok, Socket} ->
			 case ets:last(my_ets) of
			 	'$end_of_table' ->
			 		ets:insert(my_ets,{1,Socket}), gen_tcp:send(Socket,term_to_binary(1));%发送
				Other ->
					ets:insert(my_ets,{Other+1,Socket}), gen_tcp:send(Socket,term_to_binary(Other+1))
			 end,
		spawn(fun() -> wait_a_client(ListenSocket) end),%重开一个进程来绑定socket
		loop(Socket);
		{error, Msg} ->
			io:format("~p~n",[Msg])
		end.

loop(Socket) ->
	receive
		{tcp, Socket, Bin} ->
			[ID, Msg] = binary_to_term(Bin),
			case ID of
				0 -> ?MODULE:all_send(Msg),
				     loop(Socket);
				_ ->
					[{ID,SocketNum}] = ets:lookup(my_ets,ID),
					gen_tcp:send(SocketNum,term_to_binary(Msg)),
					loop(Socket)
			end;
		{tcp_closed, Socket} ->
            io:format("Server socket closed ~n")
    end.

all_send(Msg) ->
	[gen_tcp:send(Socket,term_to_binary(Msg))|| {P,Socket}<-ets:tab2list(my_ets)].

tcp_client.erl客户端:

-module(tcp_client).
-compile(export_all).

my_client() ->
	ets:new(name,[ordered_set, public, named_table, {write_concurrency, true}, {read_concurrency, true}]),
	{ok, Socket} = gen_tcp:connect("localhost", 1234, [binary, {packet,0}]),
	receive
		{tcp,_From,ID} ->
			ets:insert(name,{Socket,binary_to_term(ID)}),
			io:format("You User_ID is ~p~n",[binary_to_term(ID)])
	after 50000 ->
			io:format("time out~n")
	end,
	Pid =  spawn(fun() -> loop() end),
	gen_tcp:controlling_process(Socket, Pid),
	send_msg(Socket).

loop() ->
	receive
		{tcp,Socket,Msg} ->
			Msg1 = binary_to_term(Msg) -- "\n",
			io:format("~p~n",[Msg1]),
			loop();
		{tcp_closed, Socket} ->
	        io:format("Scoket is closed! ~n")
	end.

send_msg(Socket) ->
	ID = io:get_line("ID:"),
	Msg = io:get_line("msg:"),
	[{_Temp,UID}] = ets:lookup(name,Socket),
	Msg1 = integer_to_list(UID)++" say to you "++Msg,
	{Ii, Info} = string:to_integer(ID),
	gen_tcp:send(Socket,term_to_binary([Ii,Msg1])),
	send_msg(Socket).


 1.启动服务器

2.连接聊天服务器

返回的是你的USER_ID,也是别人找你的ID。

3.聊天 0群发 other私发:

用到以下函数:

listen:监听端口,用于生成scoket

accept:生成socket,默认与调用该方法的进程绑定

send:发送消息

controlling_process:转换绑定进程

发布了133 篇原创文章 · 获赞 8 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/fbher/article/details/93377014