Why can the server close_wait be clear when the process of the client had been killed

0

It has 4 steps on closing a TCP socket.

client close FIN_WAIT_1 FIN M => server

client FIN_WAIT_2 <= ACK M + 1 server CLOSE_WAIT

client TIME_WAIT <= FIN N server LAST_ACK

client ACK N + 1 => server CLOSED

If the client process had been killed before the server sends a response, whether the client can't send the last ACK because it had been dead? The server doesn't release 'CLOSE_WAIT'?

server.js

// npm i sleep
const http = require('http');
const sleep = require('sleep').sleep;

const server = http.createServer(async (req, res) => {
  res.statusCode = 200;
  console.log('get a request');
  await sleep(30); // sleep 30s
  res.end('goodbye\n');
  console.log('finish a request');
});
server.listen(6000);

client.js

const http = require('http');
const net = require('net');

const options = {
  port: 6000,
  host: '127.0.0.1',
  method: 'GET'
  // path: ''
};
const req = http.request(options, res => {
  res.setEncoding('utf8');
  res.on('data', function(chunk) {
    console.log('Response: ' + chunk);
  });
});
req.on('error', e => {
  console.error(`request error: ${e.message}`);
});
req.end();

setTimeout(() => {
  process.exit(1);
}, 2000); 
~ netstat -tanv | grep 6000
tcp4       0      0  127.0.0.1.6000         127.0.0.1.57786        CLOSE_WAIT  408241 146988  40426      0 0x0122 0x00000104
tcp4       0      0  127.0.0.1.57786        127.0.0.1.6000         FIN_WAIT_2  408300 146988  40434      0 0x2131 0x00000100

I expect the 'CLOSE_WAIT' is persisting on the server because it doesn't get ACK from the client, but it will be clear after the 30s.

node.js
http
https
tcp
asked on Stack Overflow Jul 15, 2019 by Miser • edited Jun 20, 2020 by Community

1 Answer

1

Here is a description of CLOSE_WAIT from RedHat:

CLOSE_WAIT - Indicates that the server has received the first FIN signal from the client and the connection is in the process of being closed. This means the socket is waiting for the application to execute close(). A socket can be in CLOSE_WAIT state indefinitely until the application closes it. Faulty scenarios would be like a file descriptor leak: server not executing close() on sockets leading to pile up of CLOSE_WAIT sockets.

This is purely a server side problem regardless of the client being killed or not. The reason you time out after 30 seconds is because the socket is being held open while you sleep for 30 seconds, then the response is allowed to send (too late of course) and close the socket.

This has nothing to do with Java vs node - just a design decision in handling the request.

answered on Stack Overflow Jul 15, 2019 by DDupont • edited Jul 15, 2019 by user207421

User contributions licensed under CC BY-SA 3.0