Skip to main content
The node:dgram module provides an implementation of UDP datagram sockets.

Import

import dgram from 'node:dgram';
// or
const dgram = require('node:dgram');

Class: dgram.Socket

Encapsulates the datagram functionality for UDP communication.

Creating a UDP Socket

import dgram from 'node:dgram';

const server = dgram.createSocket('udp4');

server.on('error', (err) => {
  console.error(`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', () => {
  const address = server.address();
  console.log(`server listening ${address.address}:${address.port}`);
});

server.bind(41234);

Events

Event: ‘close’

Emitted after a socket is closed with close().
socket.on('close', () => {
  console.log('Socket closed');
});

Event: ‘connect’

Emitted after a socket is associated to a remote address as a result of a successful connect() call.
socket.on('connect', () => {
  console.log('Socket connected');
});

Event: ‘error’

  • exception
Emitted whenever any error occurs.
socket.on('error', (err) => {
  console.error('Socket error:', err);
});

Event: ‘listening’

Emitted once the socket is addressable and can receive data.
socket.on('listening', () => {
  const address = socket.address();
  console.log(`Listening on ${address.address}:${address.port}`);
});

Event: ‘message’

  • msg The message
  • rinfo Remote address information
    • address Sender address
    • family Address family (‘IPv4’ or ‘IPv6’)
    • port Sender port
    • size Message size
Emitted when a new datagram is available.
socket.on('message', (msg, rinfo) => {
  console.log(`Received ${msg.length} bytes from ${rinfo.address}:${rinfo.port}`);
  console.log(`Message: ${msg}`);
});

Methods

socket.bind([port][, address][, callback])

  • port
  • address
  • callback
For UDP sockets, causes the socket to listen for datagram messages.
// Bind to specific port and address
socket.bind(41234, 'localhost', () => {
  console.log('Socket bound');
});

// Bind to random port
socket.bind(() => {
  console.log('Bound to port:', socket.address().port);
});

socket.bind(options[, callback])

  • options
    • port
    • address
    • exclusive
  • callback
Alternative bind with options.
socket.bind({
  address: 'localhost',
  port: 8000,
  exclusive: true
});

socket.send(msg[, offset, length][, port][, address][, callback])

  • msg
  • offset
  • length
  • port
  • address
  • callback
Broadcasts a datagram on the socket.
import { Buffer } from 'node:buffer';

const message = Buffer.from('Hello UDP');
const client = dgram.createSocket('udp4');

client.send(message, 41234, 'localhost', (err) => {
  if (err) console.error(err);
  client.close();
});

Sending Multiple Buffers

const buf1 = Buffer.from('Hello ');
const buf2 = Buffer.from('World');

client.send([buf1, buf2], 41234, 'localhost', (err) => {
  client.close();
});

socket.connect(port[, address][, callback])

  • port
  • address
  • callback
Associates the socket to a remote address and port.
const client = dgram.createSocket('udp4');

client.connect(41234, 'localhost', (err) => {
  if (err) {
    console.error(err);
    return;
  }
  
  // Can now use send() without specifying port/address
  client.send('Hello', (err) => {
    client.close();
  });
});

socket.disconnect()

Disassociates a connected socket from its remote address.
socket.disconnect();

socket.close([callback])

  • callback
Closes the underlying socket and stops listening for data.
socket.close(() => {
  console.log('Socket closed');
});

socket.address()

  • Returns:
Returns an object containing the address information for a socket.
const address = socket.address();
console.log(address);
// { address: '0.0.0.0', family: 'IPv4', port: 41234 }

socket.setBroadcast(flag)

  • flag
Sets or clears the SO_BROADCAST socket option.
socket.bind(() => {
  socket.setBroadcast(true);
  socket.send(message, 0, message.length, 41234, '255.255.255.255');
});

socket.setTTL(ttl)

  • ttl 1-255
Sets the IP_TTL socket option.
socket.setTTL(64);

socket.setMulticastTTL(ttl)

  • ttl 0-255
Sets the IP_MULTICAST_TTL socket option.
socket.setMulticastTTL(128);

socket.setMulticastLoopback(flag)

  • flag
Sets or clears the IP_MULTICAST_LOOP socket option.
socket.setMulticastLoopback(true);

socket.addMembership(multicastAddress[, multicastInterface])

  • multicastAddress
  • multicastInterface
Joins a multicast group.
socket.bind(1234, () => {
  socket.addMembership('224.0.0.114');
});

socket.dropMembership(multicastAddress[, multicastInterface])

  • multicastAddress
  • multicastInterface
Leaves a multicast group.
socket.dropMembership('224.0.0.114');

Factory Functions

dgram.createSocket(type[, callback])

  • type ‘udp4’ or ‘udp6’
  • callback Attached as a listener for ‘message’ events
  • Returns:
Creates a dgram.Socket object.
const socket = dgram.createSocket('udp4', (msg, rinfo) => {
  console.log(`Received: ${msg}`);
});

dgram.createSocket(options[, callback])

  • options
    • type ‘udp4’ or ‘udp6’ (required)
    • reuseAddr Default: false
    • ipv6Only Default: false
    • recvBufferSize SO_RCVBUF value
    • sendBufferSize SO_SNDBUF value
    • lookup Custom lookup function
  • callback
const socket = dgram.createSocket({
  type: 'udp4',
  reuseAddr: true,
  recvBufferSize: 65536,
  sendBufferSize: 65536
});

Examples

Echo Server

import dgram from 'node:dgram';

const server = dgram.createSocket('udp4');

server.on('message', (msg, rinfo) => {
  console.log(`Received: ${msg} from ${rinfo.address}:${rinfo.port}`);
  
  // Echo back
  server.send(msg, rinfo.port, rinfo.address, (err) => {
    if (err) console.error(err);
  });
});

server.on('listening', () => {
  const address = server.address();
  console.log(`Echo server listening ${address.address}:${address.port}`);
});

server.bind(41234);

UDP Client

import dgram from 'node:dgram';
import { Buffer } from 'node:buffer';

const client = dgram.createSocket('udp4');
const message = Buffer.from('Hello Server');

client.send(message, 41234, 'localhost', (err) => {
  if (err) {
    console.error(err);
    client.close();
    return;
  }
  console.log('Message sent');
});

client.on('message', (msg, rinfo) => {
  console.log(`Server response: ${msg}`);
  client.close();
});

Multicast Receiver

import dgram from 'node:dgram';

const MULTICAST_ADDR = '224.0.0.114';
const PORT = 41234;

const server = dgram.createSocket({ type: 'udp4', reuseAddr: true });

server.on('message', (msg, rinfo) => {
  console.log(`Multicast message: ${msg} from ${rinfo.address}`);
});

server.on('listening', () => {
  server.addMembership(MULTICAST_ADDR);
  console.log('Joined multicast group');
});

server.bind(PORT);

Multicast Sender

import dgram from 'node:dgram';
import { Buffer } from 'node:buffer';

const MULTICAST_ADDR = '224.0.0.114';
const PORT = 41234;

const client = dgram.createSocket('udp4');

client.bind(() => {
  client.setBroadcast(true);
  client.setMulticastTTL(128);
  
  const message = Buffer.from('Multicast message');
  
  setInterval(() => {
    client.send(message, PORT, MULTICAST_ADDR, (err) => {
      if (err) console.error(err);
    });
  }, 1000);
});

Broadcast Example

import dgram from 'node:dgram';
import { Buffer } from 'node:buffer';

const client = dgram.createSocket('udp4');

client.bind(() => {
  client.setBroadcast(true);
  
  const message = Buffer.from('Broadcast message');
  
  client.send(message, 0, message.length, 41234, '255.255.255.255', (err) => {
    if (err) console.error(err);
    console.log('Broadcast sent');
    client.close();
  });
});

Connected Socket Example

import dgram from 'node:dgram';
import { Buffer } from 'node:buffer';

const client = dgram.createSocket('udp4');

client.connect(41234, 'localhost', (err) => {
  if (err) {
    console.error('Connection failed:', err);
    return;
  }
  
  console.log('Connected to server');
  
  // Send without specifying address/port
  const message = Buffer.from('Hello');
  client.send(message, (err) => {
    if (err) console.error(err);
  });
});

client.on('message', (msg) => {
  console.log('Response:', msg.toString());
  client.disconnect();
  client.close();
});

Datagram Size Limits

The maximum size of an IPv4/v6 datagram depends on the MTU (Maximum Transmission Unit):
  • IPv4: Maximum payload is typically 65,507 bytes (65,535 - 8 bytes UDP header - 20 bytes IP header)
  • IPv6: Minimum MTU is 1280 octets
  • Practical limit: Usually 1500 bytes (Ethernet MTU)

Safe Datagram Size

const SAFE_DATAGRAM_SIZE = 508; // Conservative size

function sendSafely(socket, message, port, address) {
  if (message.length > SAFE_DATAGRAM_SIZE) {
    console.warn('Message too large, may be fragmented');
  }
  socket.send(message, port, address);
}

Error Handling

const socket = dgram.createSocket('udp4');

socket.on('error', (err) => {
  console.error('Socket error:', err.code);
  
  switch (err.code) {
    case 'EADDRINUSE':
      console.error('Address already in use');
      break;
    case 'EACCES':
      console.error('Permission denied');
      break;
    case 'ECONNREFUSED':
      console.error('Connection refused');
      break;
    default:
      console.error('Unknown error');
  }
  
  socket.close();
});

Best Practices

  1. Always handle errors - UDP is unreliable
  2. Keep messages small - Avoid fragmentation
  3. Use connected sockets - For peer-to-peer communication
  4. Implement timeouts - UDP doesn’t guarantee delivery
  5. Consider message ordering - Messages may arrive out of order
  6. Add checksums - For data integrity
  7. Implement retry logic - For critical messages