[erlang-questions] Problem detecting interrupted TCP Connection

Mitja Thomas <>
Wed Feb 2 14:21:37 CET 2011


When I reread my mail, I think I should clearify the events that 
produced the problematic behaviour.
  - I start the server (I tried it without the {ip, ...} option).
  - I connect from remote via Telnet.
  - I then take of the ethernet connection of the client. Quit telnet 
and wait a minute, so no resendings would come into my way.
-  I reestablish the Ethernet Conenction from client (actually that 
wouldnt even matter because the server should recognise the lost 
connection anyway).

The output I get is:
1> tcp:start().
Listener started
still running
still running
Starting client (#Port<0.521>)
still running
still running
still running
still running
still running    %%% Somewhere here I pulled the plug
still running
still running
still running
still running
Send ret value:ok
still running
still running
still running
still running
still running
still running
still running
still running
still running
still running
Send ret value:ok
still running
still running
still running
still running
still running
still running
still running
still running
still running
still running
Send ret value:ok
still running
...

and so forth. Normally I would have suspected a some recognition of the 
lost socket at least when the first ping message is sent after the 
connection is interrupted.

> 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 < 
> <mailto:>> 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