> ## Documentation Index
> Fetch the complete documentation index at: https://bun.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# UDP

> Use Bun's UDP API to implement services with advanced real-time requirements, such as voice chat.

## Bind a UDP socket (`Bun.udpSocket()`)

To create a new (bound) UDP socket:

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
const socket = await Bun.udpSocket({});
console.log(socket.port); // assigned by the operating system
```

Specify a port:

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
const socket = await Bun.udpSocket({
  port: 41234, // [!code ++]
});

console.log(socket.port); // 41234
```

### Send a datagram

Specify the data to send, the destination port, and the destination address.

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
socket.send("Hello, world!", 41234, "127.0.0.1");
```

The address must be a valid IP address. `send` does not perform DNS
resolution, as it is intended for low-latency operations.

### Receive datagrams

When creating your socket, add a `data` callback to handle incoming packets:

```ts server.ts icon="https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35b" theme={"theme":{"light":"github-light","dark":"dracula"}}
const server = await Bun.udpSocket({
  socket: {
    data(socket, buf, port, addr) {
      console.log(`message from ${addr}:${port}:`);
      console.log(buf.toString());
    },
  },
});

const client = await Bun.udpSocket({});
client.send("Hello!", server.port, "127.0.0.1");
```

### Connections

UDP has no concept of a connection, but many UDP exchanges (especially as a client) involve only one peer.
In that case you can connect the socket to that peer, which sets the destination address for every packet you send
and restricts incoming packets to that peer.

```ts server.ts icon="https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35b" theme={"theme":{"light":"github-light","dark":"dracula"}}
const server = await Bun.udpSocket({
  socket: {
    data(socket, buf, port, addr) {
      console.log(`message from ${addr}:${port}:`);
      console.log(buf.toString());
    },
  },
});

const client = await Bun.udpSocket({
  connect: {
    port: server.port,
    hostname: "127.0.0.1",
  },
});

client.send("Hello");
```

Connections are implemented at the operating system level, so they can also improve performance.

### Send many packets at once using `sendMany()`

To send a large volume of packets without the overhead of a system call for each, batch them with `sendMany()`.

For an unconnected socket, `sendMany` takes an array as its only argument. Each set of three array elements describes a packet:
the data to send, the target port, and the target address.

```ts server.ts icon="https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35b" theme={"theme":{"light":"github-light","dark":"dracula"}}
const socket = await Bun.udpSocket({});

// sends 'Hello' to 127.0.0.1:41234, and 'foo' to 1.1.1.1:53 in a single operation
socket.sendMany(["Hello", 41234, "127.0.0.1", "foo", 53, "1.1.1.1"]);
```

With a connected socket, `sendMany` takes an array where each element is the data to send to the peer.

```ts server.ts icon="https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35b" theme={"theme":{"light":"github-light","dark":"dracula"}}
const socket = await Bun.udpSocket({
  connect: {
    port: 41234,
    hostname: "localhost",
  },
});

socket.sendMany(["foo", "bar", "baz"]);
```

`sendMany` returns the number of packets successfully sent. Like `send`, it only takes valid IP addresses
as destinations and does not perform DNS resolution.

### Handle backpressure

A packet you send may not fit into the operating system's packet buffer. You can detect that this
has happened when:

* `send` returns `false`
* `sendMany` returns a number smaller than the number of packets you specified. In this case, Bun calls the `drain` socket handler once the socket becomes writable again:

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
const socket = await Bun.udpSocket({
  socket: {
    drain(socket) {
      // continue sending data
    },
  },
});
```

### Socket options

UDP sockets support setting various socket options:

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
const socket = await Bun.udpSocket({});

// Enable broadcasting to send packets to a broadcast address
socket.setBroadcast(true);

// Set the IP TTL (time to live) for outgoing packets
socket.setTTL(64);
```

### Multicast

Bun supports multicast operations for UDP sockets. Use `addMembership` and `dropMembership` to join and leave multicast groups:

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
const socket = await Bun.udpSocket({});

// Join a multicast group
socket.addMembership("224.0.0.1");

// Join with a specific interface
socket.addMembership("224.0.0.1", "192.168.1.100");

// Leave a multicast group
socket.dropMembership("224.0.0.1");
```

Additional multicast options:

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
// Set TTL for multicast packets (number of network hops)
socket.setMulticastTTL(2);

// Control whether multicast packets loop back to the local socket
socket.setMulticastLoopback(true);

// Specify which interface to use for outgoing multicast packets
socket.setMulticastInterface("192.168.1.100");
```

For source-specific multicast (SSM), use `addSourceSpecificMembership` and `dropSourceSpecificMembership`:

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
socket.addSourceSpecificMembership("10.0.0.1", "232.0.0.1");
socket.dropSourceSpecificMembership("10.0.0.1", "232.0.0.1");
```
