Node.js dgram モジュール詳細
Node.js のdgramモジュールは UDP(User Datagram Protocol)データグラムソケットの実装を提供します。UDP はコネクションレス型のトランスポート層プロトコルであり、TCP とは異なり、データの信頼性のある転送を保証しませんが、より低い遅延とより高い転送効率を持ちます。
主な特徴
- コネクションレス:接続を確立する必要なくデータを送信できます
- 軽量:プロトコルヘッダーのオーバーヘッドが小さい(わずか 8 バイト)
- 高効率:接続の確立と切断のオーバーヘッドがない
- 信頼性なし:データパケットの順序と到達を保証しない
コア API 解説
1. ソケットの作成
例
const dgram = require('dgram');
// 创建 UDP 套接字
const socket = dgram.createSocket('udp4'); // IPv4
// 或
const socket = dgram.createSocket('udp6'); // IPv6
// 创建 UDP 套接字
const socket = dgram.createSocket('udp4'); // IPv4
// 或
const socket = dgram.createSocket('udp6'); // IPv6
パラメータの説明
udp4:IPv4 を使用udp6:IPv6 を使用
2. ポートのバインド
例
socket.bind(41234, () => {
console.log('Socket is listening on port 41234');
});
console.log('Socket is listening on port 41234');
});
オプションのパラメータ
port:バインドするポート番号(デフォルトはランダム)address:バインドする IP アドレス(デフォルトはすべての利用可能なインターフェース)callback:バインド成功後のコールバック関数
3. メッセージの送信
例
const message = Buffer.from('Hello UDP!');
const port = 41234;
const host = '127.0.0.1';
socket.send(message, port, host, (err) => {
if (err) throw err;
console.log('Message sent');
});
const port = 41234;
const host = '127.0.0.1';
socket.send(message, port, host, (err) => {
if (err) throw err;
console.log('Message sent');
});
パラメータの説明
msg:送信するメッセージ(Buffer、String または Array)offset:Buffer 内のメッセージのオフセットlength:メッセージのバイト数port:送信先ポートaddress:送信先アドレスcallback:送信完了後のコールバック
4. メッセージの受信
例
socket.on('message', (msg, rinfo) => {
console.log(`Received ${msg.length} bytes from ${rinfo.address}:${rinfo.port}`);
console.log(`Message content: ${msg.toString()}`);
});
console.log(`Received ${msg.length} bytes from ${rinfo.address}:${rinfo.port}`);
console.log(`Message content: ${msg.toString()}`);
});
コールバック引数
msg:受信したメッセージ(Buffer)rinfo:リモートアドレス情報オブジェクトaddress:送信元 IPport:送信元ポートfamily:IP プロトコルファミリー(IPv4/IPv6)size:メッセージサイズ(バイト)
5. ソケットのクローズ
例
socket.close(() => {
console.log('Socket closed');
});
console.log('Socket closed');
});
注意事項
- クローズ後はメッセージを送受信できません
- リッスンできる
'close'イベント
イベント処理
dgramソケットは EventEmitter であり、以下のイベントをリッスンできます:
1. 'message' イベント
新しいデータグラムを受信したときに発火します
2. 'listening' イベント
ソケットがリッスンを開始したときに発火します
3. 'close' イベント
ソケットがクローズされたときに発火します
4. 'error' イベント
エラーが発生したときに発火します
例
socket.on('error', (err) => {
console.error(`Socket error:\n${err.stack}`);
socket.close();
});
console.error(`Socket error:\n${err.stack}`);
socket.close();
});
実際の応用シーン
1. リアルタイムゲーム
UDP の低遅延特性を利用してゲーム状態の更新を転送する
2. ビデオ/オーディオストリーム
少量のデータ損失は許容できるが低遅延が必要なシーン
3. DNS クエリ
DNS プロトコルは通常 UDP を使用する
4. ネットワークディスカバリープロトコル
例:SSDP(簡易サービス発見プロトコル)
完全な例
UDP サーバー
例
const dgram = require('dgram');
const server = dgram.createSocket('udp4');
server.on('message', (msg, rinfo) => {
console.log(`Server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
});
server.on('listening', () => {
const address = server.address();
console.log(`Server listening ${address.address}:${address.port}`);
});
server.bind(41234);
const server = dgram.createSocket('udp4');
server.on('message', (msg, rinfo) => {
console.log(`Server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
});
server.on('listening', () => {
const address = server.address();
console.log(`Server listening ${address.address}:${address.port}`);
});
server.bind(41234);
UDP クライアント
例
const dgram = require('dgram');
const client = dgram.createSocket('udp4');
const message = Buffer.from('Hello UDP Server');
client.send(message, 41234, 'localhost', (err) => {
if (err) throw err;
console.log('Message sent');
client.close();
});
const client = dgram.createSocket('udp4');
const message = Buffer.from('Hello UDP Server');
client.send(message, 41234, 'localhost', (err) => {
if (err) throw err;
console.log('Message sent');
client.close();
});
注意事項
- メッセージサイズの制限:UDP データグラムの最大サイズは 65507 バイト(IPv4)
- 信頼性:アプリケーション層で再送と確認応答のメカニズムを実装する必要がある
- セキュリティ:UDP は IP スプーフィングや DDoS 攻撃を受けやすい
- ファイアウォール:ファイアウォールが UDP トラフィックを許可していることを確認する
パフォーマンス最適化の提案
- ソケットアドレスの再利用(SO_REUSEADDR)
- 受信バッファサイズを適切に調整する
- メッセージをバッチ処理してシステムコールを減らす
- setRecvBufferSize() と setSendBufferSize() の使用を検討する
まとめ
Node.js のdgramモジュールは開発者に強力な UDP ネットワークプログラミング機能を提供し、低遅延・高効率を必要とするネットワークアプリケーションのシーンに特に適しています。UDP は信頼性の保証を提供しませんが、多くのリアルタイムアプリケーションでは、このトレードオフは受け入れ可能です。UDP の特性とdgramモジュールの API を理解することは、開発者がより効率的なネットワークアプリケーションを構築するのに役立ちます。