[erlang-questions] Problem detecting interrupted TCP Connection

Mitja Thomas <>
Mon Feb 7 09:22:35 CET 2011


Hello again,

has anyone tried this the way I described? I repeated the process at 
home once again with R14B01 on a windows machines, to make sure its not 
due to some outdated erlang version (can't get all the versions on old 
centos) or due to some firewall restrictions.
Any hint would be great.

Thanks in advance
Mitja

<http://erlang.org/download/otp_src_R14B01.readme>
> 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