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 通信(特にクライアントとして)は 1 つのピアのみを含みます。 そのような場合、そのピアにソケットを接続すると有益な場合があります。これにより、すべてのパケットが送信されるアドレスが指定され、 受信パケットがそのピアのみに制限されます。

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 は唯一の引数として配列を取ります。配列の 3 つの要素の各セットはパケットを記述します。 最初の項目は送信されるデータ、2 番目はターゲットポート、最後はターゲットアドレスです。

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

// 1 つの操作で '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 は DNS 解決を実行しないため、宛先として有効な IP アドレスのみを取ります。

バックプレッシャーの処理

送信しているパケットがオペレーティングシステムのパケットバッファーに適合しない場合があります。 以下の場合にこれが発生したことを検出できます。

  • sendfalse を返す
  • sendMany が指定したパケット数よりも小さい数を返す。この場合、ソケットが再び書き込み可能になると drain ソケットハンドラーが呼び出されます。
ts
const socket = await Bun.udpSocket({
  socket: {
    drain(socket) {
      // データの送信を続行
    },
  },
});

Bun by www.bunjs.com.cn 編集