| # UDP / Datagram Sockets |
| |
| Stability: 2 - Stable |
| |
| <!-- name=dgram --> |
| |
| The `dgram` module provides an implementation of UDP Datagram sockets. |
| |
| const dgram = require('dgram'); |
| const server = dgram.createSocket('udp4'); |
| |
| server.on('error', (err) => { |
| console.log(`server error:\n${err.stack}`); |
| server.close(); |
| }); |
| |
| server.on('message', (msg, rinfo) => { |
| console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`); |
| }); |
| |
| server.on('listening', () => { |
| var address = server.address(); |
| console.log(`server listening ${address.address}:${address.port}`); |
| }); |
| |
| server.bind(41234); |
| // server listening 0.0.0.0:41234 |
| |
| ## Class: dgram.Socket |
| |
| The `dgram.Socket` object is an [`EventEmitter`][] that encapsulates the |
| datagram functionality. |
| |
| New instances of `dgram.Socket` are created using [`dgram.createSocket()`][]. |
| The `new` keyword is not to be used to create `dgram.Socket` instances. |
| |
| ### Event: 'close' |
| |
| The `'close'` event is emitted after a socket is closed with [`close()`][]. |
| Once triggered, no new `'message'` events will be emitted on this socket. |
| |
| ### Event: 'error' |
| |
| * `exception` Error object |
| |
| The `'error'` event is emitted whenever any error occurs. The event handler |
| function is passed a single Error object. |
| |
| ### Event: 'listening' |
| |
| The `'listening'` event is emitted whenever a socket begins listening for |
| datagram messages. This occurs as soon as UDP sockets are created. |
| |
| ### Event: 'message' |
| |
| * `msg` Buffer object. The message |
| * `rinfo` Object. Remote address information |
| |
| The `'message'` event is emitted when a new datagram is available on a socket. |
| The event handler function is passed two arguments: `msg` and `rinfo`. The |
| `msg` argument is a [`Buffer`][] and `rinfo` is an object with the sender's |
| address information provided by the `address`, `family` and `port` properties: |
| |
| socket.on('message', (msg, rinfo) => { |
| console.log('Received %d bytes from %s:%d\n', |
| msg.length, rinfo.address, rinfo.port); |
| }); |
| |
| ### socket.addMembership(multicastAddress[, multicastInterface]) |
| |
| * `multicastAddress` String |
| * `multicastInterface` String, Optional |
| |
| Tells the kernel to join a multicast group at the given `multicastAddress` |
| using the `IP_ADD_MEMBERSHIP` socket option. If the `multicastInterface` |
| argument is not specified, the operating system will try to add membership to |
| all valid networking interfaces. |
| |
| ### socket.address() |
| |
| Returns an object containing the address information for a socket. |
| For UDP sockets, this object will contain `address`, `family` and `port` |
| properties. |
| |
| ### [socket.bind([port][, address][, callback])] |
| |
| * `port` Integer, Optional |
| * `address` String, Optional |
| * `callback` Function with no parameters, Optional. Called when |
| binding is complete. |
| |
| For UDP sockets, causes the `dgram.Socket` to listen for datagram messages on a |
| named `port` and optional `address`. If `port` is not specified, the operating |
| system will attempt to bind to a random port. If `address` is not specified, |
| the operating system will attempt to listen on all addresses. Once binding is |
| complete, a `'listening'` event is emitted and the optional `callback` function |
| is called. |
| |
| Note that specifying both a `'listening'` event listener and passing a |
| `callback` to the `socket.bind()` method is not harmful but not very |
| useful. |
| |
| A bound datagram socket keeps the Node.js process running to receive |
| datagram messages. |
| |
| If binding fails, an `'error'` event is generated. In rare case (e.g. |
| attempting to bind with a closed socket), an [`Error`][] may be thrown. |
| |
| Example of a UDP server listening on port 41234: |
| |
| const dgram = require('dgram'); |
| const server = dgram.createSocket('udp4'); |
| |
| server.on('error', (err) => { |
| console.log(`server error:\n${err.stack}`); |
| server.close(); |
| }); |
| |
| server.on('message', (msg, rinfo) => { |
| console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`); |
| }); |
| |
| server.on('listening', () => { |
| var address = server.address(); |
| console.log(`server listening ${address.address}:${address.port}`); |
| }); |
| |
| server.bind(41234); |
| // server listening 0.0.0.0:41234 |
| |
| ### socket.bind(options[, callback]) |
| |
| * `options` {Object} - Required. Supports the following properties: |
| * `port` {Number} - Required. |
| * `address` {String} - Optional. |
| * `exclusive` {Boolean} - Optional. |
| * `callback` {Function} - Optional. |
| |
| For UDP sockets, causes the `dgram.Socket` to listen for datagram messages on a |
| named `port` and optional `address` that are passed as properties of an |
| `options` object passed as the first argument. If `port` is not specified, the |
| operating system will attempt to bind to a random port. If `address` is not |
| specified, the operating system will attempt to listen on all addresses. Once |
| binding is complete, a `'listening'` event is emitted and the optional |
| `callback` function is called. |
| |
| The `options` object may contain an additional `exclusive` property that is |
| use when using `dgram.Socket` objects with the [`cluster`] module. When |
| `exclusive` is set to `false` (the default), cluster workers will use the same |
| underlying socket handle allowing connection handling duties to be shared. |
| When `exclusive` is `true`, however, the handle is not shared and attempted |
| port sharing results in an error. |
| |
| An example socket listening on an exclusive port is shown below. |
| |
| socket.bind({ |
| address: 'localhost', |
| port: 8000, |
| exclusive: true |
| }); |
| |
| ### socket.close([callback]) |
| |
| Close the underlying socket and stop listening for data on it. If a callback is |
| provided, it is added as a listener for the [`'close'`][] event. |
| |
| ### socket.dropMembership(multicastAddress[, multicastInterface]) |
| |
| * `multicastAddress` String |
| * `multicastInterface` String, Optional |
| |
| Instructs the kernel to leave a multicast group at `multicastAddress` using the |
| `IP_DROP_MEMBERSHIP` socket option. This method is automatically called by the |
| kernel when the socket is closed or the process terminates, so most apps will |
| never have reason to call this. |
| |
| If `multicastInterface` is not specified, the operating system will attempt to |
| drop membership on all valid interfaces. |
| |
| ### socket.send(buf, offset, length, port, address[, callback]) |
| |
| * `buf` Buffer object or string. Message to be sent |
| * `offset` Integer. Offset in the buffer where the message starts. |
| * `length` Integer. Number of bytes in the message. |
| * `port` Integer. Destination port. |
| * `address` String. Destination hostname or IP address. |
| * `callback` Function. Called when the message has been sent. Optional. |
| |
| Broadcasts a datagram on the socket. The destination `port` and `address` must |
| be specified. |
| |
| The `buf` argument is a [`Buffer`] object containing the message. The `offset` |
| and `length` specify the offset within the `Buffer` where the message begins |
| and the number of bytes in the message, respectively. With messages that |
| contain multi-byte characters, `offset` and `length` will be calculated with |
| respect to [byte length][] and not the character position. |
| |
| The `address` argument is a string. If the value of `address` is a host name, |
| DNS will be used to resolve the address of the host. If the `address` is not |
| specified or is an empty string, `'0.0.0.0'` or `'::0'` will be used instead. |
| It is possible, depending on the network configuration, that these defaults |
| may not work; accordingly, it is best to be explicit about the destination |
| address. |
| |
| If the socket has not been previously bound with a call to `bind`, the socket |
| is assigned a random port number and is bound to the "all interfaces" address |
| (`'0.0.0.0'` for `udp4` sockets, `'::0'` for `udp6` sockets.) |
| |
| An optional `callback` function may be specified to as a way of reporting |
| DNS errors or for determining when it is safe to reuse the `buf` object. |
| Note that DNS lookups delay the time to send for at least one tick of the |
| Node.js event loop. |
| |
| The only way to know for sure that the datagram has been sent is by using a |
| `callback`. If an error occurs and a `callback` is given, the error will be |
| passed as the first argument to the `callback`. If a `callback` is not given, |
| the error is emitted as an `'error'` event on the `socket` object. |
| |
| Example of sending a UDP packet to a random port on `localhost`; |
| |
| const dgram = require('dgram'); |
| const message = new Buffer('Some bytes'); |
| const client = dgram.createSocket('udp4'); |
| client.send(message, 0, message.length, 41234, 'localhost', (err) => { |
| client.close(); |
| }); |
| |
| **A Note about UDP datagram size** |
| |
| The maximum size of an `IPv4/v6` datagram depends on the `MTU` |
| (_Maximum Transmission Unit_) and on the `Payload Length` field size. |
| |
| - The `Payload Length` field is `16 bits` wide, which means that a normal |
| payload exceed 64K octets _including_ the internet header and data |
| (65,507 bytes = 65,535 − 8 bytes UDP header − 20 bytes IP header); |
| this is generally true for loopback interfaces, but such long datagram |
| messages are impractical for most hosts and networks. |
| |
| - The `MTU` is the largest size a given link layer technology can support for |
| datagram messages. For any link, `IPv4` mandates a minimum `MTU` of `68` |
| octets, while the recommended `MTU` for IPv4 is `576` (typically recommended |
| as the `MTU` for dial-up type applications), whether they arrive whole or in |
| fragments. |
| |
| For `IPv6`, the minimum `MTU` is `1280` octets, however, the mandatory minimum |
| fragment reassembly buffer size is `1500` octets. The value of `68` octets is |
| very small, since most current link layer technologies, like Ethernet, have a |
| minimum `MTU` of `1500`. |
| |
| It is impossible to know in advance the MTU of each link through which |
| a packet might travel. Sending a datagram greater than the receiver `MTU` will |
| not work because the packet will get silently dropped without informing the |
| source that the data did not reach its intended recipient. |
| |
| ### socket.setBroadcast(flag) |
| |
| * `flag` Boolean |
| |
| Sets or clears the `SO_BROADCAST` socket option. When set to `true`, UDP |
| packets may be sent to a local interface's broadcast address. |
| |
| ### socket.setMulticastLoopback(flag) |
| |
| * `flag` Boolean |
| |
| Sets or clears the `IP_MULTICAST_LOOP` socket option. When set to `true`, |
| multicast packets will also be received on the local interface. |
| |
| ### socket.setMulticastTTL(ttl) |
| |
| * `ttl` Integer |
| |
| Sets the `IP_MULTICAST_TTL` socket option. While TTL generally stands for |
| "Time to Live", in this context it specifies the number of IP hops that a |
| packet is allowed to travel through, specifically for multicast traffic. Each |
| router or gateway that forwards a packet decrements the TTL. If the TTL is |
| decremented to 0 by a router, it will not be forwarded. |
| |
| The argument passed to to `socket.setMulticastTTL()` is a number of hops |
| between 0 and 255. The default on most systems is `1` but can vary. |
| |
| ### socket.setTTL(ttl) |
| |
| * `ttl` Integer |
| |
| Sets the `IP_TTL` socket option. While TTL generally stands for "Time to Live", |
| in this context it specifies the number of IP hops that a packet is allowed to |
| travel through. Each router or gateway that forwards a packet decrements the |
| TTL. If the TTL is decremented to 0 by a router, it will not be forwarded. |
| Changing TTL values is typically done for network probes or when multicasting. |
| |
| The argument to `socket.setTTL()` is a number of hops between 1 and 255. |
| The default on most systems is 64 but can vary. |
| |
| ### socket.ref() |
| |
| By default, binding a socket will cause it to block the Node.js process from |
| exiting as long as the socket is open. The `socket.unref()` method can be used |
| to exclude the socket from the reference counting that keeps the Node.js |
| process active. The `socket.ref()` method adds the socket back to the reference |
| counting and restores the default behavior. |
| |
| Calling `socket.ref()` multiples times will have no additional effect. |
| |
| The `socket.ref()` method returns a reference to the socket so calls can be |
| chained. |
| |
| ### socket.unref() |
| |
| By default, binding a socket will cause it to block the Node.js process from |
| exiting as long as the socket is open. The `socket.unref()` method can be used |
| to exclude the socket from the reference counting that keeps the Node.js |
| process active, allowing the process to exit even if the socket is still |
| listening. |
| |
| Calling `socket.unref()` multiple times will have no addition effect. |
| |
| The `socket.unref()` method returns a reference to the socket so calls can be |
| chained. |
| |
| ### Change to asynchronous `socket.bind()` behavior |
| |
| As of Node.js v0.10, [`dgram.Socket#bind()`][] changed to an asynchronous |
| execution model. Legacy code that assumes synchronous behavior, as in the |
| following example: |
| |
| const s = dgram.createSocket('udp4'); |
| s.bind(1234); |
| s.addMembership('224.0.0.114'); |
| |
| Must be changed to pass a callback function to the [`dgram.Socket#bind()`][] |
| function: |
| |
| const s = dgram.createSocket('udp4'); |
| s.bind(1234, () => { |
| s.addMembership('224.0.0.114'); |
| }); |
| |
| ## `dgram` module functions |
| |
| ### dgram.createSocket(options[, callback]) |
| * `options` Object |
| * `callback` Function. Attached as a listener to `'message'` events. |
| * Returns: Socket object |
| |
| Creates a `dgram.Socket` object. The `options` argument is an object that |
| should contain a `type` field of either `udp4` or `udp6` and an optional |
| boolean `reuseAddr` field. |
| |
| When `reuseAddr` is `true` [`socket.bind()`][] will reuse the address, even if |
| another process has already bound a socket on it. `reuseAddr` defaults to |
| `false`. An optional `callback` function can be passed specified which is added |
| as a listener for `'message'` events. |
| |
| Once the socket is created, calling [`socket.bind()`][] will instruct the |
| socket to begin listening for datagram messages. When `address` and `port` are |
| not passed to [`socket.bind()`][] the method will bind the socket to the "all |
| interfaces" address on a random port (it does the right thing for both `udp4` |
| and `udp6` sockets). The bound address and port can be retrieved using |
| [`socket.address().address`][] and [`socket.address().port`][]. |
| |
| ## dgram.createSocket(type[, callback]) |
| |
| * `type` String. Either 'udp4' or 'udp6' |
| * `callback` Function. Attached as a listener to `'message'` events. |
| Optional |
| * Returns: Socket object |
| |
| Creates a `dgram.Socket` object of the specified `type`. The `type` argument |
| can be either `udp4` or `udp6`. An optional `callback` function can be passed |
| which is added as a listener for `'message'` events. |
| |
| Once the socket is created, calling [`socket.bind()`][] will instruct the |
| socket to begin listening for datagram messages. When `address` and `port` are |
| not passed to [`socket.bind()`][] the method will bind the socket to the "all |
| interfaces" address on a random port (it does the right thing for both `udp4` |
| and `udp6` sockets). The bound address and port can be retrieved using |
| [`socket.address().address`][] and [`socket.address().port`][]. |
| |
| [`EventEmitter`]: events.html |
| [`Buffer`]: buffer.html |
| [`'close'`]: #dgram_event_close |
| [`addMembership()`]: #dgram_socket_addmembership_multicastaddress_multicastinterface |
| [`close()`]: #dgram_socket_close_callback |
| [`dgram.createSocket()`]: #dgram_dgram_createsocket_options_callback |
| [`dgram.Socket#bind()`]: #dgram_socket_bind_options_callback |
| [`Error`]: errors.html#errors_class_error |
| [`socket.address().address`]: #dgram_socket_address |
| [`socket.address().port`]: #dgram_socket_address |
| [`socket.bind()`]: #dgram_socket_bind_port_address_callback |
| [byte length]: buffer.html#buffer_class_method_buffer_bytelength_string_encoding |