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 는 유일한 인수로 배열을 받습니다. 3 개의 배열 요소 세트는 각각 패킷을 설명합니다. 첫 번째 항목은 전송할 데이터, 두 번째는 대상 포트, 마지막은 대상 주소입니다.

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 는 DNS 확인을 수행하지 않으므로 유효한 IP 주소만 대상으로 받습니다.

백프레셔 처리

전송 중인 패킷이 운영 체제의 패킷 버퍼에 맞지 않을 수 있습니다. 이는 다음 경우 감지할 수 있습니다.

  • sendfalse 를 반환
  • sendMany 가 지정한 패킷 수보다 작은 숫자를 반환. 이 경우 소켓이 다시 쓰기 가능해지면 drain 소켓 핸들러가 호출됩니다.
ts
const socket = await Bun.udpSocket({
  socket: {
    drain(socket) {
      // 데이터 전송 계속
    },
  },
});

Bun by www.bunjs.com.cn 편집