[erlang-questions] Problem detecting interrupted TCP Connection

Joe Armstrong <>
Wed Feb 2 13:45:49 CET 2011


I tried your code and it worked beautifully - but I had to remove the
{ip, {xxx,...}} term - if you omit the IP then you this will default to the
local interface

then you can do
   > telnet localhost 8999, or
   > telnet 127.0.0.1 8999, or
   > telnet <My eth0 IPv4 address> 8999

all worked as expected

/Joe


On Wed, Feb 2, 2011 at 1:08 PM, Mitja Thomas <>wrote:

> Hello Folks,
>
> I'm new to this Mailing List, so my question might already have been
> answered at some point. Still I got a strange behaviour in a TCP Session
> which I just cant figur out.
>
> Beckground:
> I have a Server who listens on a Port for incomming TCP Connections and
> handles them in a User List. When something happens for this User (on the
> other side, which doesnt matter for the problem), the user is informed and
> can send commands. When the TCP Connection ist closed, the Socket is closed
> and the User will be erased from the User list.
>
> Problem:
> When the user somehow disconnects his TCP/IP Connection and closes the
> client application, my server dont get the tcp_closed Event and the user is
> still present in the List. Well I know this is the way TCP should behave,
> thus the server tries to send a packet to the Socket once in while and
> should receive and Error of some kind. But it does not, it just keeps
> "sending", without actually sending TCP Packets.
> The Problem is well explained in gen_tcp manual page and an example how it
> should be handled in such a way with an application ping is given. But I
> just dont the {error, timeout} while trying to send to the broken TCP
> Socket.
>
> I broke it down to a simple Server, who just pings the client and tried
> various ways to do it. Im pretty sure, Im doing something wrong, but I just
> dont know what. Any Help is appreciated.
>
> Regards
> Mitja
>
> sample Code (Client is normally a simple Telnet):
> -module(tcp).
> -compile(export_all).
>
> start() ->
>    {ok, Listener} = gen_tcp:listen(8999, [binary, {ip, {xxx,xxx,xxx,xxx}},
> {active, true}, {packet, 0}, {keepalive, true}, {reuseaddr, true},
> {send_timeout_close, true}, {send_timeout, 100}]),
>    io:format("Listener started~n"),
>    acceptor(Listener).
>
> acceptor(Listener) ->
>        case gen_tcp:accept(Listener, 1000) of
>        {ok, Socket} ->
>                io:format("Starting client (~p)\n", [Socket]),
>            Pid=spawn_link(fun()->loop(Socket) end),
>                gen_tcp:controlling_process(Socket, Pid),
>            acceptor(Listener);
>
>        {error, timeout} -> io:format("still running\n"),
> acceptor(Listener);
>
>        X -> io:format("SocketError:~p~n", [X])
>    end.
>
> loop(Socket) ->
>    receive
>        {tcp, Socket, Data} ->
>            io:format("Client: Received '~p'\n", [Data]),
>            loop(Socket);
>
>        {tcp_closed, Socket} ->
>            % This is the desired close Event
>            io:format("Client: Socket closed by remote\n");
>
>        {tcp_error, Socket, Reason} ->
>            io:format("Client: Socket error '~p'\n", [Reason])
>    after
>        1000 ->
>            case gen_tcp:send(Socket, "Ping\r\n") of
>                                Ret ->
>                                        % If Ping fails the output should be
> =/= ok
>                                        io:format("Send ret value:~p~n",
> [Ret]),
>                                        loop(Socket)
>                        end
>    end.
>
>


More information about the erlang-questions mailing list