Documentation Index
Fetch the complete documentation index at: https://bun.zhcndoc.com/llms.txt
Use this file to discover all available pages before exploring further.
绑定一个 UDP 套接字 (Bun.udpSocket())
要创建一个新的(绑定的)UDP 套接字:
const socket = await Bun.udpSocket({});
console.log(socket.port); // 由操作系统分配
指定端口:
const socket = await Bun.udpSocket({
port: 41234,
});
console.log(socket.port); // 41234
发送数据报
指定要发送的数据,以及目标端口和地址。
socket.send("Hello, world!", 41234, "127.0.0.1");
注意,地址必须是有效的 IP 地址 —— send 不执行 DNS 解析,因为它旨在用于低延迟操作。
接收数据报
创建套接字时,添加回调以指定接收数据包时应执行的操作:
server.tsconst 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 通信(尤其是作为客户端时)只涉及一个对等方。
在这种情况下,将套接字“连接”到该对等方可能会带来好处,这指定了所有数据包发送的地址,
并限制只接收来自该对等方的数据包。
server.tsconst 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 接受一个数组作为唯一参数。每三项描述一个数据包:
第一项是要发送的数据,第二项是目标端口,第三项是目标地址。
server.tsconst 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"]);
With a connected socket, sendMany takes an array, where each element represents the data to be sent to the peer.
server.tsconst socket = await Bun.udpSocket({
connect: {
port: 41234,
hostname: "localhost",
},
});
socket.sendMany(["foo", "bar", "baz"]);
sendMany 返回成功发送的数据包数。与 send 一样,sendMany 只接受有效的 IP 地址作为目标,
因为它不执行 DNS 解析。
处理背压
可能会发生你发送的数据包无法放入操作系统的数据包缓冲区。当出现以下情况时,你可以检测到这种情况:
send 返回 false
sendMany 返回的数字小于你指定的数据包数量。在这种情况下,一旦套接字变得可写,
drain 套接字处理程序会被调用:
const socket = await Bun.udpSocket({
socket: {
drain(socket) {
// 继续发送数据
},
},
});
套接字选项
UDP 套接字支持设置各种套接字选项:
const socket = await Bun.udpSocket({});
// 启用广播,发送数据包到广播地址
socket.setBroadcast(true);
// 设置出站数据包的 IP TTL(生存时间)
socket.setTTL(64);
Bun 支持 UDP 套接字的多播操作。使用 addMembership 和 dropMembership 加入和离开多播组:
const socket = await Bun.udpSocket({});
// 加入多播组
socket.addMembership("224.0.0.1");
// 指定接口加入多播组
socket.addMembership("224.0.0.1", "192.168.1.100");
// 离开多播组
socket.dropMembership("224.0.0.1");
其他多播选项:
// 设置多播包的 TTL(网络跳数)
socket.setMulticastTTL(2);
// 控制多播包是否回环到本地套接字
socket.setMulticastLoopback(true);
// 指定用于出站多播包的接口
socket.setMulticastInterface("192.168.1.100");
对于源特定多播(SSM),使用 addSourceSpecificMembership 和 dropSourceSpecificMembership:
socket.addSourceSpecificMembership("10.0.0.1", "232.0.0.1");
socket.dropSourceSpecificMembership("10.0.0.1", "232.0.0.1");