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