Erlang之简便聊天室

本文介绍了一个使用Erlang编写的TCP聊天室。客户端包括启动服务器、连接聊天服务器并获取USER_ID进行群发和私发聊天的功能。关键函数包括listen用于监听端口,accept创建socket并与进程绑定,send负责发送消息,而controlling_process则用于改变绑定的进程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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:转换绑定进程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值