Skip to content

綁定 UDP 套接字(Bun.udpSocket()

要創建新的(綁定的)UDP 套接字:

ts
const socket = await Bun.udpSocket({});
console.log(socket.port); // 由操作系統分配

指定端口:

ts
const socket = await Bun.udpSocket({
  port: 41234, 
});

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

發送數據報

指定要發送的數據,以及目標端口和地址。

ts
socket.send("Hello, world!", 41234, "127.0.0.1");

注意地址必須是有效的 IP 地址 - send 不執行 DNS 解析,因為它旨在用於低延遲操作。

接收數據報

在創建套接字時,添加回調以指定收到數據包時應執行的操作:

ts
const server = await Bun.udpSocket({
  socket: {
    data(socket, buf, port, addr) {
      console.log(`來自 ${addr}:${port} 的消息:`);
      console.log(buf.toString());
    },
  },
});

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

連接

雖然 UDP 沒有連接的概念,但許多 UDP 通信(尤其是作為客戶端)只涉及一個對等點。 在這種情況下,將套接字連接到該對等點可能有益,這指定了所有數據包發送到的地址 並限制僅從該對等點接收傳入數據包。

ts
const server = await Bun.udpSocket({
  socket: {
    data(socket, buf, port, addr) {
      console.log(`來自 ${addr}:${port} 的消息:`);
      console.log(buf.toString());
    },
  },
});

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

client.send("Hello");

因為連接是在操作系統級別實現的,所以你也可能觀察到性能優勢。

使用 sendMany() 一次發送多個數據包

如果你想一次發送大量數據包,將它們批量處理在一起可以避免為每個數據包進行系統調用的開銷。sendMany() API 使這成為可能:

對於未連接的套接字,sendMany 將數組作為唯一參數。每三個數組元素描述一個數據包: 第一項是要發送的數據,第二項是目標端口,最後一項是目標地址。

ts
const socket = await Bun.udpSocket({});

// 在單個操作中將 'Hello' 發送到 127.0.0.1:41234,將 'foo' 發送到 1.1.1.1:53
socket.sendMany(["Hello", 41234, "127.0.0.1", "foo", 53, "1.1.1.1"]);

對於已連接的套接字,sendMany 只需一個數組,其中每個元素表示要發送到對等點的數據。

ts
const socket = await Bun.udpSocket({
  connect: {
    port: 41234,
    hostname: "localhost",
  },
});

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

sendMany 返回成功發送的數據包數量。與 send 一樣,sendMany 只接受有效的 IP 地址作為目標,因為它不執行 DNS 解析。

處理背壓

你發送的數據包可能不適合操作系統的數據包緩沖區。當發生這種情況時:

  • send 返回 false
  • sendMany 返回的數字小於你指定的數據包數量。在這種情況下,一旦套接字再次可寫,drain 套接字處理程序將被調用:
ts
const socket = await Bun.udpSocket({
  socket: {
    drain(socket) {
      // 繼續發送數據
    },
  },
});

Bun學習網由www.bunjs.com.cn整理維護