TCP 套接字关闭但未被进程检测到

TCP socket closing but not detected by process

我有一个允许连接的服务器,然后根据它收到的消息,服务器应该做一些事情(目前还没有实现)但是如果套接字关闭,服务器也应该提醒我它没有。

sloop(Listen)->
    {ok, Socket} = gen_tcp:accept(Listen),
    io:format("Someone connected"),
    master ! {add,Socket},
    io:format("Point A reached"),
    spawn(fun() -> sloop(Listen) end),
    io:format("Point B reached"),
    receive
        {tcp, Socket, Bin} ->
             case read(Bin) of
                    {join,Channel} -> 
                                tracker ! {self(),get,Socket},
                                receive 
                                    void -> 
                                        master ! {delete, Socket},
                                        A = lists:dropwhile(fun(A) -> A /= Channel end, registered()),
                                        case A of
                                            [H|_] -> H ! {add,Socket};
                                            _ -> register(Channel,spawn(fun() -> listenerSocket([]) end))
                                        end,
                                    Channel ! {add, Socket},
                                    tracker ! {insert,Socket, Channel};
                                    {ok, Value} -> 
                                        Value ! {delete,Socket},
                                        tracker ! {delete,Socket},
                                        A = lists:dropwhile(fun(A) -> A /= Channel end, registered()),
                                        case A of
                                            [H|_] -> H ! {add,Socket};
                                            _ -> register(Channel,spawn(fun() -> listenerSocket([]) end))
                                        end,
                                    Channel ! {add, Socket},
                                    tracker ! {insert,Socket, Channel};
                     {message, Msg} ->  
                                tracker ! {self(),get,Socket},
                                receive 
                                    {ok, Value} -> Value ! {broadcast, Msg}
                                end
                end;
        {tcp_closed, Socket} -> io:format("Someone disconnected")
    end
end.

每当我打开一个套接字并将其指向 localhost:2266 时,shell 打印 "Someone connected" 、 "Point A reached"、"Point B reached" 但是每当我关闭套接字时使用 tcp_gen:close/1 服务器不打印 "Someone disconnected".

修复代码的格式可能会有所帮助,因为这会告诉您 {tcp_closed, Socket} 模式匹配是 case 子句,而不是 receive 子句。我认为您打算将其作为最外层 receive.

的子句

请注意 sloop/1 函数不是递归的,这意味着它的最外层 receive 仅处理一条消息,处理该消息,然后 returns。也许你有其他代码你没有显示重复调用 sloop/1,但无论哪种方式,你都需要某种循环遍历 sloop/1,同时将你的 {tcp_closed, Socket} 模式匹配移动到最外层receive,让您的应用程序正确处理多条消息。

您需要递归调用您的侦听器函数。如前所述,侦听器函数将在第一条消息后终止,因此不会侦听 gen_tcp:close 消息。处理成功消息后重新进入循环即可。

sloop(Listen)->
    {ok, Socket} = gen_tcp:accept(Listen),
    io:format("Someone connected"),
    master ! {add,Socket}, % <-- not sure what this does
    io:format("Point A reached"),
    spawn(fun() -> sloop(Listen) end),
    io:format("Point B reached").

loop_internal(Socket) ->
    inet:setopts(Socket,[{active,once}]),
    receive
        {tcp, Socket, Bin} -> 
            do_your_stuff(Bin),
            %% your stuff removed for brevity
            loop_internal(Socket);
        {tcp_closed, Socket} -> io:format("Someone disconnected")
    end
end.