dgram: support Uint8Array input to send()
Fixes: https://github.com/nodejs/node/issues/11954 Refs: https://github.com/nodejs/node/pull/11961 PR-URL: https://github.com/nodejs/node/pull/11985 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Timothy Gu <timothygu99@gmail.com>
This commit is contained in:
parent
90403dd1d0
commit
2dc1053b0a
@ -245,20 +245,23 @@ chained.
|
||||
<!-- YAML
|
||||
added: v0.1.99
|
||||
changes:
|
||||
- version: REPLACEME
|
||||
pr-url: https://github.com/nodejs/node/pull/11985
|
||||
description: The `msg` parameter can be an Uint8Array now.
|
||||
- version: REPLACEME
|
||||
pr-url: https://github.com/nodejs/node/pull/10473
|
||||
description: The `address` parameter is always optional now.
|
||||
- version: v6.0.0
|
||||
pr-url: https://github.com/nodejs/node/pull/5929
|
||||
description: On success, `callback` will now be called with an `error`
|
||||
argument of `null` rather than `0`.
|
||||
- version: REPLACEME
|
||||
pr-url: https://github.com/nodejs/node/pull/10473
|
||||
description: The `address` parameter is always optional now.
|
||||
- version: v5.7.0
|
||||
pr-url: https://github.com/nodejs/node/pull/4374
|
||||
description: The `msg` parameter can be an array now. Also, the `offset`
|
||||
and `length` parameters are optional now.
|
||||
-->
|
||||
|
||||
* `msg` {Buffer|string|array} Message to be sent
|
||||
* `msg` {Buffer|Uint8Array|string|array} Message to be sent
|
||||
* `offset` {number} Integer. Optional. Offset in the buffer where the message starts.
|
||||
* `length` {number} Integer. Optional. Number of bytes in the message.
|
||||
* `port` {number} Integer. Destination port.
|
||||
@ -269,7 +272,8 @@ Broadcasts a datagram on the socket. The destination `port` and `address` must
|
||||
be specified.
|
||||
|
||||
The `msg` argument contains the message to be sent.
|
||||
Depending on its type, different behavior can apply. If `msg` is a `Buffer`,
|
||||
Depending on its type, different behavior can apply. If `msg` is a `Buffer`
|
||||
or `Uint8Array`,
|
||||
the `offset` and `length` specify the offset within the `Buffer` where the
|
||||
message begins and the number of bytes in the message, respectively.
|
||||
If `msg` is a `String`, then it is automatically converted to a `Buffer`
|
||||
@ -299,7 +303,7 @@ the error is emitted as an `'error'` event on the `socket` object.
|
||||
|
||||
Offset and length are optional, but if you specify one you would need to
|
||||
specify the other. Also, they are supported only when the first
|
||||
argument is a `Buffer`.
|
||||
argument is a `Buffer` or `Uint8Array`.
|
||||
|
||||
Example of sending a UDP packet to a random port on `localhost`;
|
||||
|
||||
|
16
lib/dgram.js
16
lib/dgram.js
@ -29,6 +29,7 @@ const UV_UDP_REUSEADDR = process.binding('constants').os.UV_UDP_REUSEADDR;
|
||||
|
||||
const UDP = process.binding('udp_wrap').UDP;
|
||||
const SendWrap = process.binding('udp_wrap').SendWrap;
|
||||
const { isUint8Array } = process.binding('util');
|
||||
|
||||
const BIND_STATE_UNBOUND = 0;
|
||||
const BIND_STATE_BINDING = 1;
|
||||
@ -266,10 +267,12 @@ Socket.prototype.sendto = function(buffer,
|
||||
|
||||
|
||||
function sliceBuffer(buffer, offset, length) {
|
||||
if (typeof buffer === 'string')
|
||||
if (typeof buffer === 'string') {
|
||||
buffer = Buffer.from(buffer);
|
||||
else if (!(buffer instanceof Buffer))
|
||||
throw new TypeError('First argument must be a buffer or string');
|
||||
} else if (!isUint8Array(buffer)) {
|
||||
throw new TypeError('First argument must be a Buffer, ' +
|
||||
'Uint8Array or string');
|
||||
}
|
||||
|
||||
offset = offset >>> 0;
|
||||
length = length >>> 0;
|
||||
@ -285,7 +288,7 @@ function fixBufferList(list) {
|
||||
var buf = list[i];
|
||||
if (typeof buf === 'string')
|
||||
newlist[i] = Buffer.from(buf);
|
||||
else if (!(buf instanceof Buffer))
|
||||
else if (!isUint8Array(buf))
|
||||
return null;
|
||||
else
|
||||
newlist[i] = buf;
|
||||
@ -359,8 +362,9 @@ Socket.prototype.send = function(buffer,
|
||||
if (!Array.isArray(buffer)) {
|
||||
if (typeof buffer === 'string') {
|
||||
list = [ Buffer.from(buffer) ];
|
||||
} else if (!(buffer instanceof Buffer)) {
|
||||
throw new TypeError('First argument must be a buffer or a string');
|
||||
} else if (!isUint8Array(buffer)) {
|
||||
throw new TypeError('First argument must be a Buffer, ' +
|
||||
'Uint8Array or string');
|
||||
} else {
|
||||
list = [ buffer ];
|
||||
}
|
||||
|
@ -15,23 +15,30 @@ const received = [];
|
||||
|
||||
client.on('listening', common.mustCall(() => {
|
||||
const port = client.address().port;
|
||||
|
||||
client.send(toSend[0], 0, toSend[0].length, port);
|
||||
client.send(toSend[1], port);
|
||||
client.send([toSend[2]], port);
|
||||
client.send(toSend[3], 0, toSend[3].length, port);
|
||||
|
||||
client.send(new Uint8Array(toSend[0]), 0, toSend[0].length, port);
|
||||
client.send(new Uint8Array(toSend[1]), port);
|
||||
client.send([new Uint8Array(toSend[2])], port);
|
||||
client.send(new Uint8Array(Buffer.from(toSend[3])),
|
||||
0, toSend[3].length, port);
|
||||
}));
|
||||
|
||||
client.on('message', common.mustCall((buf, info) => {
|
||||
received.push(buf.toString());
|
||||
|
||||
if (received.length === toSend.length) {
|
||||
if (received.length === toSend.length * 2) {
|
||||
// The replies may arrive out of order -> sort them before checking.
|
||||
received.sort();
|
||||
|
||||
const expected = toSend.map(String).sort();
|
||||
const expected = toSend.concat(toSend).map(String).sort();
|
||||
assert.deepStrictEqual(received, expected);
|
||||
client.close();
|
||||
}
|
||||
}, toSend.length));
|
||||
}, toSend.length * 2));
|
||||
|
||||
client.bind(0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user