[erlang-questions] Problem detecting interrupted TCP Connection

Mitja Thomas mitja.thomas1@REDACTED
Wed Feb 2 17:27:08 CET 2011


Hi,

I wont even argue there. Flow Control via {active, false} is really 
relevant especially at connection establishment.
But I tried it either way. This is just a very simplified version. The 
connection works fine, the server recognises that a client has 
connected. The problem occurs later, which I guess you can see in my 
server Output.

Mitja

> Hello,
>
> I might be wrong, but I think that opening a socket in the active mode
> introduces a race condition: the socket can deliver TCP messages to the
> acceptor process instead of the loop process even before the call to set
> a new controlling process.
>
> As a general recommendation from discussions on this list I'd say that
> the socket should be opened in {active, false} mode, then the control
> should be transferred to the appropriate process which should set mode
> to {active, once} whenever it is ready to handle another TCP message
> and thus implement a form of flow control.
>
>
> Please correct me if this is not so.
>
>
> HTH,
>
> Ladislav Lenart
>
>
> Joe Armstrong wrote:
>> 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 
>> <mitja.thomas1@REDACTED>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.
>>>
>>>
>>
>
>
>


-- 
Mitja Thomas
GE FD
Lösungsmanagement

Telefon: 0441 8000 - 4916
E-Mail: mitja.thomas@REDACTED
___________________________________

EWE TEL GmbH
Cloppenburger Straße 310
26133 Oldenburg

Handelsregister Amtsgericht Oldenburg HRB 3723
Vorsitzender des Aufsichtsrates: Dr. Werner Brinker
Geschäftsführung: Konrad Meier (Vorsitzender), Dirk Brameier,
Ulf Heggenberger, Norbert Westfal
Homepage: http://www.ewetel.de

Wir stehen für starken Service. Versprochen!

+++ Besuchen Sie uns auf der Hausmesse der Finanz Informatik vom 16. bis zum 18.11.2010
  in Frankfurt a.M. Sie finden uns auf dem Stand P-04.13 +++



More information about the erlang-questions mailing list