Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
net, http: add backlog parameter to .listen()
  • Loading branch information
erikdubbelboer authored and bnoordhuis committed Apr 18, 2012
1 parent b12b2b8 commit 3d69bbf
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 18 deletions.
7 changes: 6 additions & 1 deletion doc/api/http.markdown
Expand Up @@ -117,14 +117,19 @@ sent to the server on that socket.

If a client connection emits an 'error' event - it will forwarded here.

### server.listen(port, [hostname], [callback])
### server.listen(port, [hostname], [backlog], [callback])

Begin accepting connections on the specified port and hostname. If the
hostname is omitted, the server will accept connections directed to any
IPv4 address (`INADDR_ANY`).

To listen to a unix socket, supply a filename instead of port and hostname.

Backlog is the maximum length of the queue of pending connections.
The actual length will be determined by your OS through sysctl settings such as
`tcp_max_syn_backlog` and `somaxconn` on linux. The default value of this
parameter is 511 (not 512).

This function is asynchronous. The last parameter `callback` will be added as
a listener for the ['listening'](net.html#event_listening_) event.
See also [net.Server.listen()](net.html#server.listen).
Expand Down
7 changes: 6 additions & 1 deletion doc/api/net.markdown
Expand Up @@ -121,12 +121,17 @@ The `connectListener` parameter will be added as an listener for the
This class is used to create a TCP or UNIX server.
A server is a `net.Socket` that can listen for new incoming connections.

### server.listen(port, [host], [listeningListener])
### server.listen(port, [host], [backlog], [listeningListener])

Begin accepting connections on the specified `port` and `host`. If the
`host` is omitted, the server will accept connections directed to any
IPv4 address (`INADDR_ANY`). A port value of zero will assign a random port.

Backlog is the maximum length of the queue of pending connections.
The actual length will be determined by your OS through sysctl settings such as
`tcp_max_syn_backlog` and `somaxconn` on linux. The default value of this
parameter is 511 (not 512).

This function is asynchronous. When the server has been bound,
['listening'](#event_listening_) event will be emitted.
the last parameter `listeningListener` will be added as an listener for the
Expand Down
40 changes: 24 additions & 16 deletions lib/net.js
Expand Up @@ -56,7 +56,7 @@ if (process.env.NODE_DEBUG && /net/.test(process.env.NODE_DEBUG)) {


function isPipeName(s) {
return typeof s === 'string' && toPort(s) === false;
return typeof s === 'string' && toNumber(s) === false;
}


Expand Down Expand Up @@ -161,7 +161,7 @@ exports.Stream = Socket; // Legacy naming.
Socket.prototype.listen = function() {
var self = this;
self.on('connection', arguments[0]);
listen(self, null, null);
listen(self, null, null, null);
};


Expand Down Expand Up @@ -747,7 +747,7 @@ util.inherits(Server, events.EventEmitter);
exports.Server = Server;


function toPort(x) { return (x = Number(x)) >= 0 ? x : false; }
function toNumber(x) { return (x = Number(x)) >= 0 ? x : false; }


var createServerHandle = exports._createServerHandle =
Expand Down Expand Up @@ -786,7 +786,7 @@ var createServerHandle = exports._createServerHandle =
};


Server.prototype._listen2 = function(address, port, addressType) {
Server.prototype._listen2 = function(address, port, addressType, backlog) {
var self = this;
var r = 0;

Expand All @@ -805,7 +805,10 @@ Server.prototype._listen2 = function(address, port, addressType) {
self._handle.onconnection = onconnection;
self._handle.socket = self;

r = self._handle.listen(self._backlog || 128);
// Use a backlog of 512 entries. We pass 511 to the listen() call because
// the kernel does: backlogsize = roundup_pow_of_two(backlogsize + 1);
// which will thus give us a backlog of 512 entries.
r = self._handle.listen(backlog || 511);

if (r) {
self._handle.close();
Expand All @@ -822,15 +825,15 @@ Server.prototype._listen2 = function(address, port, addressType) {
};


function listen(self, address, port, addressType) {
function listen(self, address, port, addressType, backlog) {
if (process.env.NODE_UNIQUE_ID) {
var cluster = require('cluster');
cluster._getServer(self, address, port, addressType, function(handle) {
self._handle = handle;
self._listen2(address, port, addressType);
self._listen2(address, port, addressType, backlog);
});
} else {
self._listen2(address, port, addressType);
self._listen2(address, port, addressType, backlog);
}
}

Expand All @@ -843,36 +846,41 @@ Server.prototype.listen = function() {
self.once('listening', lastArg);
}

var port = toPort(arguments[0]);
var port = toNumber(arguments[0]);

// The third optional argument is the backlog size.
// When the ip is omitted it can be the second argument.
var backlog = toNumber(arguments[1]) || toNumber(arguments[2]);

var TCP = process.binding('tcp_wrap').TCP;

if (arguments.length == 0 || typeof arguments[0] == 'function') {
// Don't bind(). OS will assign a port with INADDR_ANY.
// The port can be found with server.address()
listen(self, null, null);
listen(self, null, null, backlog);

} else if (arguments[0] instanceof TCP) {
self._handle = arguments[0];
listen(self, null, -1, -1);
listen(self, null, -1, -1, backlog);

} else if (isPipeName(arguments[0])) {
// UNIX socket or Windows pipe.
var pipeName = self._pipeName = arguments[0];
listen(self, pipeName, -1, -1);
listen(self, pipeName, -1, -1, backlog);

} else if (typeof arguments[1] == 'undefined' ||
typeof arguments[1] == 'function') {
typeof arguments[1] == 'function' ||
typeof arguments[1] == 'number') {
// The first argument is the port, no IP given.
listen(self, '0.0.0.0', port, 4);
listen(self, '0.0.0.0', port, 4, backlog);

} else {
// The first argument is the port, the second an IP
// The first argument is the port, the second an IP.
require('dns').lookup(arguments[1], function(err, ip, addressType) {
if (err) {
self.emit('error', err);
} else {
listen(self, ip || '0.0.0.0', port, ip ? addressType : 4);
listen(self, ip || '0.0.0.0', port, ip ? addressType : 4, backlog);
}
});
}
Expand Down
25 changes: 25 additions & 0 deletions test/simple/test-net-server-bind.js
Expand Up @@ -62,9 +62,34 @@ server2.listen(common.PORT + 1, function() {
});


// Backlog argument

var address3;
var server3 = net.createServer(function(socket) { });

server3.listen(common.PORT + 2, '0.0.0.0', 127, function() {
address3 = server3.address();
console.log('address3 %j', address3);
server3.close();
});


// Backlog argument without host argument

var address4;
var server4 = net.createServer(function(socket) { });

server4.listen(common.PORT + 3, 127, function() {
address4 = server4.address();
console.log('address4 %j', address4);
server4.close();
});


process.on('exit', function() {
assert.ok(address0.port > 100);
assert.equal(common.PORT, address1.port);
assert.equal(common.PORT + 1, address2.port);
assert.equal(common.PORT + 2, address3.port);
assert.equal(common.PORT + 3, address4.port);
});

2 comments on commit 3d69bbf

@AndreasMadsen
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bnoordhuis
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, fixed in c56d155.

Please sign in to comment.