[erlang-questions] Problem detecting interrupted TCP Connection
Ladislav Lenart
lenartlad@REDACTED
Wed Feb 2 14:20:34 CET 2011
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.
>>
>>
>
More information about the erlang-questions
mailing list