erlang gen_tcp:send返回close疑问


背景:我用erlang编写了一个聊天系统的服务端与客户端的程序。客户端连接到服务器并发送登陆请求,服务端能够接收到该请求并将处理后的数据用gen_tcp:send返回给客户端的时,出现“error,closed”的报错显示。在网上苦苦寻找原因未果,想请问一下出错原因。

相关代码:
客户端:

   
  -module(client).
  
-compile(export_all).
client_send_recv() ->
{ok,Socket} = gen_tcp:connect("localhost",8888,[binary,{packet,0}]),
spawn(client,log,[Socket]),%%发送登陆请求,具体省略不放上来
recv(Socket).%%接收服务端返回来的信息
recv(Socket) ->
receive
{tcp,Socket,Bin} ->
Msg = binary_to_term(Bin),
case Msg of
%%登陆相关信息
{wrong} ->
io:format('The password is wrong,please again'),
log(Socket);
{false} ->
io:format("The account has been login"),
log(Socket);
{login,Pid,Username,{Channel,Ip1,Time1,Ip2,Time2,Ip3,Time3}} ->
io:format("Welcome!~w",[Username]),
io:format("you have been login as ~n~w:~w~n~w:~w~n~w:~w~n",[Time1,Ip1,Time2,Ip2,Time3,Ip3]),
io:format("your channel is ~w~n",[Channel]),
send(Socket,Pid,Username);
{newuser,Pid,Username,Channel} ->
io:format("Welcome!New user!Your channel is ~w~n",[Channel]),
send(Socket,Pid,Username);
%%聊天信息
{Channel,Username,Massage} ->
io:format("[~w]~w:~w~n",[Channel,Username,Massage])
end,
recv(Socket)
end,
recv(Socket).

服务端:

   
  -module(server).
  
-include("dbtest.erl").%%对mnesia数据库的初始化及查询插入函数的设置
-compile(export_all).

start() ->
init(),%%对数据库进行初始化
register(log_server,spawn(server,log_server,[])),
port().

port() ->
{ok,LScoket} = gen_tcp:listen(8888,[binary,{packet,0},{active,false},{reuseaddr,true}]),
spawn(fun()-> accept(LScoket) end).

accept(LScoket) ->
{ok,Socket} = gen_tcp:accept(LScoket),
spawn(fun() -> accept(LScoket) end),
case gen_tcp:recv(Socket,0) of
{ok,Data} ->
case binary_to_term(Data) of
%%登陆请求
{{Username,Password,Ip},log} ->
log_server ! {Socket,{Username,Password,Ip},log};
{Pid,Channel,Username,Massage,send} ->
Pid ! {Channel,Username,Massage,send}
end;
{error,Reason} ->
io:format("error to receive the data,for:~w~n",[Reason])
end.

log_server() ->
receive
{Socket,{Username,Password,Ip},log} ->
%%检查是否重复登陆
case search_active(Username) of
false ->
%%检查用户是否存在
case search_user(Username,Password,Ip) of
{true,Ip1,Time1,Ip2,Time2,Ip3,Time3} ->

Pid = spawn(server,chart_server,[Socket]),
Channel = insert_active(Username,Pid),
Msg = {login,Pid,Username,{Channel,Ip1,Time1,Ip2,Time2,Ip3,Time3}},
ok = gen_tcp:send(Socket,term_to_binary(Msg));**%%这一句出问题,报错{error,closed}**

false ->

wrong ->


end;
true ->

{Other} ->

end.

erlang

比利丶海灵顿 10 years, 11 months ago

Your Answer