Problem detecting interrupted TCP Connection
Mitja Thomas
mitja.thomas1@REDACTED
Wed Feb 2 13:08:52 CET 2011
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