He is a bit of code where a server is created to listen on port 2222:
import { createServer } from 'net';
const server = createServer((c) => {
c.setEncoding('utf8');
c.on('data', (data) => {
console.log('server', data);
c.write(data);
});
c.on('error', (e) => { throw e; });
});
server.listen(2222);
and the code to create a connection to the server to send a simple 'hello' that the server will respond back to. After 2 seconds, the socket gets destroyed.
import { createConnection } from 'net';
const socket = createConnection({ localPort: 9999, port: 2222, host: 'localhost' });
socket.setEncoding('utf8');
socket.on('data', (data) => {
console.log('socket data', data);
});
socket.on('connect', () => {
socket.write('hello');
});
socket.setTimeout(2000);
socket.on('timeout', () => { socket.destroy(); console.log('destroyed'); });
socket.on('error', (e) => { throw e; });
This code works well the first time it is called.
It will fail on subsequent calls with:
Error: connect EADDRINUSE 127.0.0.1:2222 - Local (0.0.0.0:9999)
errno: -48,
code: 'EADDRINUSE',
syscall: 'connect',
address: '127.0.0.1',
port: 2222
It took me a while to figure it out, but the problem comes from trying to bind the socket on an outbound port: localPort: 9999
. Without specifying this parameter, the OS will select a free port, and the program won't crash.
When specifying it, a cooldown of ~15s is required before the socket being re-usable again.
- Is there a way to properly destroy the socket so that it becomes immediately available again?
- If not, is there a way to verify that the socket is "cooling down", but will eventually be available again? I'd like to distinguish the case where I just have to wait from the one where the socket has been actively taken by another process, and won't be released to the pool of free sockets.
Any theory on why the socket is not available after the program exists is welcome!
CodePudding user response:
Why are you specifying a local port in the first place? You almost never want to do that. If you don't, it'll work.
Any theory on why the socket is not available after the program exists is welcome!
The OS keeps the port in use for a while to be able to receive packets and tell the sender that the socket is gone.
Is there a way to properly destroy the socket so that it becomes immediately available again?
You can set the "linger" socket option to 0, so it'll become available immediately again, but again, you shouldn't get yourself in this situation in the first time. Consider whether you want to specify the local port. You usually don't.
is there a way to verify that the socket is "cooling down"
It'll be in the CLOSE_WAIT state.
CodePudding user response:
The socket is going into a CLOSE_WAIT state, so you have to wait until it is available again before you can reconnect. You can try to avoid this by:
Removing the source socket and letting the platform pick a random ephemeral one for you (as you have already found out).
Closing the connection at the server end first (so the CLOSE_WAIT ends up there). See server.close();
Resetting the client connection. See socket.resetAndDestroy()