1

This question is an extension to this previously asked question:

I implemented the solution given by jxh with following params:

SO_KEEPALIVE = Enabled  
TCP_KEEPIDLE = 120 secs  
TCP_KEEPINTVL = 75 secs  
TCP_KEEPCNT = 1

Then why the server still waits forever for client to respond?

Also I found out on internet that

kill <pid> actually sends SIGTERM to the given process.

So I used ps -o pid,cmd,state command after 'killing' the telnet application.

I saw that the telnet process was still there but with process state = T, i.e. it was in STOPPED state

P.S.: I do not have much knowledge of Linux Signals, please consider that.

Community
  • 1
  • 1
0xF1
  • 6,046
  • 2
  • 27
  • 50

2 Answers2

2

Because the client hasn't exited yet, being still in STOPPED state, and therefore hasn't closed its connections either.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • Ok!! But I have one doubt that I have already set socket options to close the connection if idle. Won't the connection be idle if the client is stopped. – 0xF1 Aug 19 '13 at 10:40
  • 1
    @nishant No. TCP keepalive will periodically send probes on the TCP connection, and if no positive response is received back, it will eventually time out and your server recv() call will return -1. However the TCP connection is still alive, It is managed by your operating system. It operates independently of what your client process does, as long as the client process is alive, and the machine and TCP stack of the client can still be reached. Try cutting the power at the client machine, or the network connection. – nos Aug 19 '13 at 17:29
  • 1
    There are no socket options that 'close the connection if idle'. KEep-alive does the *opposite* if anything. As long as there is a functioning TCP at the other end, and a viable network path to it every time it operates, keepalive cannot have any effect. – user207421 Aug 19 '13 at 22:46
1

Since the client processes are still alive, then the TCP stack in the kernel will process the keep-alive packets it receives with an acknowledgement packet back to the sender of the packet. So, even though the connection is indeed idle, the connection will never be closed since the kernel is happily processing the packets.

On a real network, given your parameters, the connection would be closed if the ACK from the client machine ever got lost. On your setup, since the client and server are on the same machine, your network will be essentially lossless.

It is unclear to me how you got your telnet sessions in this state. SIGTERM will not put a process in the stopped state. The process goes into stopped state when receiving SIGSTOP (and usually SIGTSTP, but it seems telnet ignores that one). I suggest that perhaps you sent that signal by mistake, or you suspended the session (with ^]z). When that happened, you should have seen in the window, the one with your telnet session, generate output like:

[1]+  Stopped                 telnet ...

This is printed by the shell. When the telnet process is stopped, it won't process the SIGTERM until after it is placed in the foreground.

A SIGKILL (done with kill -9 <pid>) will be processed immediately.

jxh
  • 69,070
  • 8
  • 110
  • 193
  • Well I got my answer, thanks to all, but even with `kill -9 ` the output was `[2]+ Stopped telnet 164.99.90.215 5000` , however the process was terminated/killed. – 0xF1 Aug 20 '13 at 06:14
  • My mistake: The `Stopped` state was not the output of `kill -9 ` rather I used `telnet &`, the succeeding '&' caused that output. `kill -9 -` gave output as: `[2]+ Killed telnet `. But why is the output delayed, its giving correct output after an 'Enter'? – 0xF1 Aug 20 '13 at 06:29
  • 1
    @nishant: That is just how most shells behave. – jxh Aug 20 '13 at 06:33