mirror of https://github.com/nodejs/node.git
dgram: introduce `reuseAddr` option
Introduce new signature for both `dgram.createSocket` method and `dgram.Socket` constructor: dgram.createSocket(options, [listener]) Options should contain `type` property and may contain `reuseAddr` property. When `reuseAddr` is `true` - SO_REUSEADDR will be issued on socket on bind. fix #7415 Signed-off-by: Fedor Indutny <fedor@indutny.com>archived-io.js-v0.10
parent
c20b209dbb
commit
592be014b6
|
@ -22,8 +22,13 @@ You have to change it to this:
|
||||||
|
|
||||||
|
|
||||||
## dgram.createSocket(type, [callback])
|
## dgram.createSocket(type, [callback])
|
||||||
|
## dgram.createSocket(options, [callback])
|
||||||
|
|
||||||
* `type` String. Either 'udp4' or 'udp6'
|
* `type` String. Either 'udp4' or 'udp6'
|
||||||
|
* `options` Object. Should contain a `type` property and could contain
|
||||||
|
`reuseAddr` property. `false` by default.
|
||||||
|
When `reuseAddr` is `true` - `socket.bind()` will reuse address, even if the
|
||||||
|
other process has already bound a socket on it.
|
||||||
* `callback` Function. Attached as a listener to `message` events.
|
* `callback` Function. Attached as a listener to `message` events.
|
||||||
Optional
|
Optional
|
||||||
* Returns: Socket object
|
* Returns: Socket object
|
||||||
|
@ -41,7 +46,7 @@ with `socket.address().address` and `socket.address().port`.
|
||||||
## Class: dgram.Socket
|
## Class: dgram.Socket
|
||||||
|
|
||||||
The dgram Socket class encapsulates the datagram functionality. It
|
The dgram Socket class encapsulates the datagram functionality. It
|
||||||
should be created via `dgram.createSocket(type, [callback])`.
|
should be created via `dgram.createSocket(...)`
|
||||||
|
|
||||||
### Event: 'message'
|
### Event: 'message'
|
||||||
|
|
||||||
|
|
15
lib/dgram.js
15
lib/dgram.js
|
@ -22,6 +22,7 @@
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var util = require('util');
|
var util = require('util');
|
||||||
var events = require('events');
|
var events = require('events');
|
||||||
|
var constants = require('constants');
|
||||||
|
|
||||||
var UDP = process.binding('udp_wrap').UDP;
|
var UDP = process.binding('udp_wrap').UDP;
|
||||||
|
|
||||||
|
@ -96,6 +97,11 @@ exports._createSocketHandle = function(address, port, addressType, fd) {
|
||||||
function Socket(type, listener) {
|
function Socket(type, listener) {
|
||||||
events.EventEmitter.call(this);
|
events.EventEmitter.call(this);
|
||||||
|
|
||||||
|
if (typeof type === 'object') {
|
||||||
|
var options = type;
|
||||||
|
type = options.type;
|
||||||
|
}
|
||||||
|
|
||||||
var handle = newHandle(type);
|
var handle = newHandle(type);
|
||||||
handle.owner = this;
|
handle.owner = this;
|
||||||
|
|
||||||
|
@ -105,6 +111,9 @@ function Socket(type, listener) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.fd = null; // compatibility hack
|
this.fd = null; // compatibility hack
|
||||||
|
|
||||||
|
// If true - UV_UDP_REUSEADDR flag will be set
|
||||||
|
this._reuseAddr = options && options.reuseAddr;
|
||||||
|
|
||||||
if (util.isFunction(listener))
|
if (util.isFunction(listener))
|
||||||
this.on('message', listener);
|
this.on('message', listener);
|
||||||
}
|
}
|
||||||
|
@ -196,7 +205,11 @@ Socket.prototype.bind = function(/*port, address, callback*/) {
|
||||||
if (!self._handle)
|
if (!self._handle)
|
||||||
return; // handle has been closed in the mean time
|
return; // handle has been closed in the mean time
|
||||||
|
|
||||||
var err = self._handle.bind(ip, port || 0, /*flags=*/ 0);
|
var flags = 0;
|
||||||
|
if (self._reuseAddr)
|
||||||
|
flags |= constants.UV_UDP_REUSEADDR;
|
||||||
|
|
||||||
|
var err = self._handle.bind(ip, port || 0, flags);
|
||||||
if (err) {
|
if (err) {
|
||||||
self.emit('error', errnoException(err, 'bind'));
|
self.emit('error', errnoException(err, 'bind'));
|
||||||
self._bindState = BIND_STATE_UNBOUND;
|
self._bindState = BIND_STATE_UNBOUND;
|
||||||
|
|
|
@ -1071,12 +1071,17 @@ void DefineSystemConstants(Handle<Object> target) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DefineUVConstants(Handle<Object> target) {
|
||||||
|
NODE_DEFINE_CONSTANT(target, UV_UDP_REUSEADDR);
|
||||||
|
}
|
||||||
|
|
||||||
void DefineConstants(Handle<Object> target) {
|
void DefineConstants(Handle<Object> target) {
|
||||||
DefineErrnoConstants(target);
|
DefineErrnoConstants(target);
|
||||||
DefineWindowsErrorConstants(target);
|
DefineWindowsErrorConstants(target);
|
||||||
DefineSignalConstants(target);
|
DefineSignalConstants(target);
|
||||||
DefineOpenSSLConstants(target);
|
DefineOpenSSLConstants(target);
|
||||||
DefineSystemConstants(target);
|
DefineSystemConstants(target);
|
||||||
|
DefineUVConstants(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace node
|
} // namespace node
|
||||||
|
|
|
@ -157,7 +157,10 @@ if (process.argv[2] !== 'child') {
|
||||||
})(x);
|
})(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
var sendSocket = dgram.createSocket('udp4');
|
var sendSocket = dgram.createSocket({
|
||||||
|
type: 'udp4',
|
||||||
|
reuseAddr: true
|
||||||
|
});
|
||||||
|
|
||||||
// bind the address explicitly for sending
|
// bind the address explicitly for sending
|
||||||
// INADDR_BROADCAST to only one interface
|
// INADDR_BROADCAST to only one interface
|
||||||
|
@ -201,7 +204,10 @@ if (process.argv[2] !== 'child') {
|
||||||
|
|
||||||
if (process.argv[2] === 'child') {
|
if (process.argv[2] === 'child') {
|
||||||
var receivedMessages = [];
|
var receivedMessages = [];
|
||||||
var listenSocket = dgram.createSocket('udp4');
|
var listenSocket = dgram.createSocket({
|
||||||
|
type: 'udp4',
|
||||||
|
reuseAddr: true
|
||||||
|
});
|
||||||
|
|
||||||
listenSocket.on('message', function(buf, rinfo) {
|
listenSocket.on('message', function(buf, rinfo) {
|
||||||
// receive udp messages only sent from parent
|
// receive udp messages only sent from parent
|
||||||
|
|
Loading…
Reference in New Issue