📨 Node-RED UDP ノードガイド

📚 目次

📖 1. 概要

UDP(User Datagram Protocol)は、コネクションレスの軽量プロトコルです。TCPと異なり、接続の確立や再送制御を行わないため、高速で軽量な通信が可能です。

📮 郵便に例えると:UDPは「はがき」のようなものです。送ったら終わり。届いたかどうかの確認はしません。一方TCPは「書留郵便」で、相手に届いたことを確認します。

UDPの特徴

📥 UDP In

UDP In

役割: 指定ポートでUDPパケットを受信

📤 UDP Out

UDP Out

役割: UDPパケットを送信(ユニキャスト/ブロードキャスト)

⚖️ 2. UDP vs TCP の違い

特性 UDP TCP
接続 コネクションレス(接続不要) コネクション型(接続確立必要)
信頼性 なし(パケットロスあり得る) あり(再送制御)
順序保証 なし あり
速度 高速 比較的遅い
オーバーヘッド 小さい(8バイト) 大きい(20バイト〜)
ブロードキャスト 可能 不可
用途例 DNS、動画配信、ゲーム、センサーデータ Web、メール、ファイル転送

💡 使い分けのポイント:

⚙️ 3. UDP In ノード

動作モード

モード説明用途
Listen for udp messages 指定ポートでUDPパケットを待ち受け UDPサーバー、センサーデータ受信
Listen for multicast messages マルチキャストグループに参加して受信 グループ通信

主要プロパティ

プロパティ説明
待ち受け受信モードudp messages
ポート待ち受けポート8000
IPvIPv4 または IPv6ipv4
グループマルチキャストグループ(マルチキャスト時)224.0.0.1
出力出力形式String / Buffer

受信時の msg プロパティ

プロパティ説明
msg.payload受信データ(String または Buffer)
msg.ip送信元IPアドレス
msg.port送信元ポート番号

⚙️ 4. UDP Out ノード

送信先の設定方法

設定方法説明
ノードで固定 Address と Port をノード設定で指定
メッセージで動的指定 msg.ip と msg.port で送信先を指定

主要プロパティ

プロパティ説明
送信送信モードudp message
アドレス送信先アドレス192.168.1.100
ポート送信先ポート8000
ブロードキャストアドレスブロードキャストアドレス192.168.1.255
ローカルポートローカルポートを固定8001

ブロードキャストアドレス

// 限定ブロードキャスト(同一サブネット内) 192.168.1.255 ← サブネット 192.168.1.0/24 の場合 // ローカルブロードキャスト 255.255.255.255

送信時に設定できる msg プロパティ

プロパティ説明
msg.payload送信データ(String または Buffer)
msg.ip送信先IPアドレス(動的指定時)
msg.port送信先ポート(動的指定時)

🔧 5. 実用的な使用パターン

📥 サンプルフローのインポート方法:

  1. 下のサンプルフローJSONをコピー
  2. Node-REDエディタで メニュー → 読み込み を選択
  3. JSONをペーストして「読み込み」をクリック

このサンプルフローには、以下で説明するパターンの実例が含まれています。

⚠️ テスト方法:

UDPのテストには以下のツールを使用できます:

netcat でのテスト例

# UDP送信 echo "Hello UDP" | nc -u localhost 8000 # UDP受信(別ターミナル) nc -ul 8000
📥 サンプルフローJSON(クリックで展開)
[ { "id": "udp_sample_tab", "type": "tab", "label": "UDP サンプル", "disabled": false, "info": "" }, { "id": "udp_comment1", "type": "comment", "z": "udp_sample_tab", "name": "━━━ 基本: UDP受信 ━━━", "info": "ポート8000でUDPパケットを受信", "x": 170, "y": 40, "wires": [] }, { "id": "udp_in_basic", "type": "udp in", "z": "udp_sample_tab", "name": "UDP In :8000", "iface": "", "port": "8000", "ipv": "udp4", "multicast": "false", "group": "", "datatype": "utf8", "x": 170, "y": 100, "wires": [["udp_debug_received", "udp_func_info"]] }, { "id": "udp_debug_received", "type": "debug", "z": "udp_sample_tab", "name": "受信データ", "active": true, "tosidebar": true, "console": false, "tostatus": true, "complete": "payload", "targetType": "msg", "statusVal": "ip", "statusType": "msg", "x": 390, "y": 100, "wires": [] }, { "id": "udp_func_info", "type": "function", "z": "udp_sample_tab", "name": "送信元情報", "func": "msg.senderInfo = {\n ip: msg.ip,\n port: msg.port,\n data: msg.payload,\n timestamp: new Date().toISOString()\n};\nnode.status({fill: \"green\", shape: \"dot\", text: msg.ip + \":\" + msg.port});\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 390, "y": 140, "wires": [["udp_debug_info"]] }, { "id": "udp_debug_info", "type": "debug", "z": "udp_sample_tab", "name": "送信元情報", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "senderInfo", "targetType": "msg", "x": 590, "y": 140, "wires": [] }, { "id": "udp_comment2", "type": "comment", "z": "udp_sample_tab", "name": "━━━ 基本: UDP送信(ユニキャスト) ━━━", "info": "", "x": 210, "y": 220, "wires": [] }, { "id": "udp_inject_unicast", "type": "inject", "z": "udp_sample_tab", "name": "ユニキャスト送信", "props": [{"p": "payload"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "Hello UDP!", "payloadType": "str", "x": 180, "y": 280, "wires": [["udp_out_unicast"]] }, { "id": "udp_out_unicast", "type": "udp out", "z": "udp_sample_tab", "name": "UDP Out (localhost:8000)", "addr": "localhost", "iface": "", "port": "8000", "ipv": "udp4", "outport": "", "base64": false, "multicast": "false", "x": 440, "y": 280, "wires": [] }, { "id": "udp_comment3", "type": "comment", "z": "udp_sample_tab", "name": "━━━ ブロードキャスト送信 ━━━", "info": "同一サブネット内の全デバイスに送信", "x": 190, "y": 360, "wires": [] }, { "id": "udp_inject_broadcast", "type": "inject", "z": "udp_sample_tab", "name": "ブロードキャスト送信", "props": [{"p": "payload"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "BROADCAST: Hello everyone!", "payloadType": "str", "x": 190, "y": 420, "wires": [["udp_out_broadcast"]] }, { "id": "udp_out_broadcast", "type": "udp out", "z": "udp_sample_tab", "name": "UDP Broadcast", "addr": "255.255.255.255", "iface": "", "port": "8000", "ipv": "udp4", "outport": "", "base64": false, "multicast": "broadcast", "x": 440, "y": 420, "wires": [] }, { "id": "udp_comment4", "type": "comment", "z": "udp_sample_tab", "name": "━━━ JSON データの送受信 ━━━", "info": "", "x": 190, "y": 500, "wires": [] }, { "id": "udp_in_json", "type": "udp in", "z": "udp_sample_tab", "name": "UDP In :8001 (JSON)", "iface": "", "port": "8001", "ipv": "udp4", "multicast": "false", "group": "", "datatype": "utf8", "x": 190, "y": 560, "wires": [["udp_func_json_parse"]] }, { "id": "udp_func_json_parse", "type": "function", "z": "udp_sample_tab", "name": "JSONパース", "func": "try {\n msg.data = JSON.parse(msg.payload);\n msg.data.receivedAt = new Date().toISOString();\n msg.data.from = msg.ip;\n node.status({fill: \"green\", shape: \"dot\", text: \"JSON OK\"});\n} catch(e) {\n msg.data = {error: \"Invalid JSON\", raw: msg.payload};\n node.status({fill: \"red\", shape: \"ring\", text: \"JSON Error\"});\n}\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 430, "y": 560, "wires": [["udp_debug_json"]] }, { "id": "udp_debug_json", "type": "debug", "z": "udp_sample_tab", "name": "JSON データ", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "data", "targetType": "msg", "x": 610, "y": 560, "wires": [] }, { "id": "udp_inject_json", "type": "inject", "z": "udp_sample_tab", "name": "JSON送信", "props": [{"p": "payload"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "{\"sensor\":\"temp\",\"value\":25.5,\"unit\":\"C\"}", "payloadType": "str", "x": 170, "y": 620, "wires": [["udp_out_json"]] }, { "id": "udp_out_json", "type": "udp out", "z": "udp_sample_tab", "name": "UDP Out :8001", "addr": "localhost", "iface": "", "port": "8001", "ipv": "udp4", "outport": "", "base64": false, "multicast": "false", "x": 400, "y": 620, "wires": [] }, { "id": "udp_comment5", "type": "comment", "z": "udp_sample_tab", "name": "━━━ 受信元への返信(エコー) ━━━", "info": "msg.ip と msg.port を使って返信", "x": 200, "y": 700, "wires": [] }, { "id": "udp_in_echo", "type": "udp in", "z": "udp_sample_tab", "name": "UDP In :8002", "iface": "", "port": "8002", "ipv": "udp4", "multicast": "false", "group": "", "datatype": "utf8", "x": 170, "y": 760, "wires": [["udp_func_echo"]] }, { "id": "udp_func_echo", "type": "function", "z": "udp_sample_tab", "name": "エコー処理", "func": "// 送信元情報を保持(返信用)\nvar replyTo = {\n ip: msg.ip,\n port: msg.port\n};\n\n// エコー応答を作成\nmsg.payload = \"[ECHO] \" + msg.payload;\n\n// 返信先を設定\nmsg.ip = replyTo.ip;\nmsg.port = replyTo.port;\n\nnode.status({fill: \"blue\", shape: \"dot\", text: \"Reply to \" + replyTo.ip});\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 390, "y": 760, "wires": [["udp_out_echo", "udp_debug_echo"]] }, { "id": "udp_out_echo", "type": "udp out", "z": "udp_sample_tab", "name": "UDP Reply (msg.ip/port)", "addr": "", "iface": "", "port": "", "ipv": "udp4", "outport": "", "base64": false, "multicast": "false", "x": 620, "y": 760, "wires": [] }, { "id": "udp_debug_echo", "type": "debug", "z": "udp_sample_tab", "name": "エコー送信", "active": true, "tosidebar": true, "console": false, "tostatus": true, "complete": "payload", "targetType": "msg", "statusVal": "ip", "statusType": "msg", "x": 590, "y": 800, "wires": [] }, { "id": "udp_comment6", "type": "comment", "z": "udp_sample_tab", "name": "━━━ 定期的なセンサーデータ送信 ━━━", "info": "", "x": 210, "y": 880, "wires": [] }, { "id": "udp_inject_periodic", "type": "inject", "z": "udp_sample_tab", "name": "3秒ごと", "props": [{"p": "payload"}], "repeat": "3", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 160, "y": 940, "wires": [["udp_func_sensor"]] }, { "id": "udp_func_sensor", "type": "function", "z": "udp_sample_tab", "name": "センサーデータ生成", "func": "var temp = (20 + Math.random() * 10).toFixed(1);\nvar humidity = Math.floor(40 + Math.random() * 40);\n\nmsg.payload = JSON.stringify({\n deviceId: \"sensor-001\",\n temperature: parseFloat(temp),\n humidity: humidity,\n timestamp: new Date().toISOString()\n});\n\nnode.status({fill: \"green\", shape: \"dot\", text: temp + \"°C\"});\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 380, "y": 940, "wires": [["udp_out_sensor", "udp_debug_sensor"]] }, { "id": "udp_out_sensor", "type": "udp out", "z": "udp_sample_tab", "name": "UDP Broadcast :8003", "addr": "255.255.255.255", "iface": "", "port": "8003", "ipv": "udp4", "outport": "", "base64": false, "multicast": "broadcast", "x": 620, "y": 940, "wires": [] }, { "id": "udp_debug_sensor", "type": "debug", "z": "udp_sample_tab", "name": "送信データ", "active": true, "tosidebar": true, "console": false, "tostatus": true, "complete": "payload", "targetType": "msg", "statusVal": "\"送信\"", "statusType": "str", "x": 590, "y": 980, "wires": [] } ]

使用パターン

パターン1: 基本UDP送受信

サンプルフローの「基本: UDP受信」「基本: UDP送信(ユニキャスト)」を参照してください。

データ UDP Out
UDP In 表示

ポイント:

パターン2: ブロードキャスト送信

サンプルフローの「ブロードキャスト送信」を参照してください。

メッセージ UDP Out (255.255.255.255)

ポイント:

パターン3: JSONデータの送受信

サンプルフローの「JSON データの送受信」を参照してください。

JSON生成 UDP送信 UDP受信 JSONパース 確認

ポイント:

パターン4: 受信元への返信(エコー)

サンプルフローの「受信元への返信(エコー)」を参照してください。

受信 処理 返信(msg.ip/port)

ポイント:

パターン5: 定期的なセンサーデータ送信

サンプルフローの「定期的なセンサーデータ送信」を参照してください。

3秒ごと センサーデータ生成 ブロードキャスト

ポイント:

📝 6. 演習問題

演習1: UDPメッセージの送受信 初級

📋 課題: ポート9000でUDPパケットを受信し、デバッグサイドバーに表示してください。同時に、送信ノードでテストメッセージを送れるようにしてください。

🎯 要求仕様:

✅ 成功の条件:

💡 ヒント

UDP In ノード:

  • Listen for: udp messages
  • on port: 9000
  • Output: String

UDP Out ノード:

  • to: localhost
  • port: 9000
✅ 解答例フロー
[ {"id": "ex1_tab", "type": "tab", "label": "演習1"}, {"id": "ex1_udp_in", "type": "udp in", "z": "ex1_tab", "name": "UDP In :9000", "iface": "", "port": "9000", "ipv": "udp4", "multicast": "false", "group": "", "datatype": "utf8", "x": 170, "y": 100, "wires": [["ex1_debug"]]}, {"id": "ex1_debug", "type": "debug", "z": "ex1_tab", "name": "受信データ", "active": true, "tosidebar": true, "console": false, "tostatus": true, "complete": "payload", "targetType": "msg", "statusVal": "ip", "statusType": "msg", "x": 390, "y": 100, "wires": []}, {"id": "ex1_inject", "type": "inject", "z": "ex1_tab", "name": "テスト送信", "props": [{"p": "payload"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "Hello UDP!", "payloadType": "str", "x": 170, "y": 180, "wires": [["ex1_udp_out"]]}, {"id": "ex1_udp_out", "type": "udp out", "z": "ex1_tab", "name": "UDP Out", "addr": "localhost", "iface": "", "port": "9000", "ipv": "udp4", "outport": "", "base64": false, "multicast": "false", "x": 380, "y": 180, "wires": []} ]

演習2: 送信元への返信 初級

📋 課題: 受信したデータに「[REPLY]」を付けて、送信元に返信してください。

🎯 要求仕様:

✅ 成功の条件:

💡 ヒント

Change ノード:

// msg.payload に「[REPLY] 」を先頭に付ける // ルール: msg.payload を「値の代入」で設定 // 型: JSONata式 // 式: "[REPLY] " & msg.payload // ※ msg.ip と msg.port はそのまま保持される

UDP Out ノード:

  • to: 空欄(msg.ip を使用)
  • port: 空欄(msg.port を使用)
✅ 解答例フロー
[ {"id": "ex2_tab", "type": "tab", "label": "演習2"}, {"id": "ex2_udp_in", "type": "udp in", "z": "ex2_tab", "name": "UDP In :9001", "iface": "", "port": "9001", "ipv": "udp4", "multicast": "false", "group": "", "datatype": "utf8", "x": 170, "y": 100, "wires": [["ex2_change"]]}, {"id": "ex2_change", "type": "change", "z": "ex2_tab", "name": "返信作成", "rules": [{"t": "set", "p": "payload", "pt": "msg", "to": "\"[REPLY] \" & msg.payload", "tot": "jsonata"}], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 370, "y": 100, "wires": [["ex2_udp_out"]]}, {"id": "ex2_udp_out", "type": "udp out", "z": "ex2_tab", "name": "UDP Reply", "addr": "", "iface": "", "port": "", "ipv": "udp4", "outport": "", "base64": false, "multicast": "false", "x": 560, "y": 100, "wires": []} ]

演習3: 複数デバイスからのデータ集約 中級

📋 課題: 複数のデバイス(シミュレート)からJSONデータを受信し、デバイスIDごとに最新値を保持してください。

🎯 要求仕様:

✅ 成功の条件:

💡 ヒント

Function ノード:

var data = JSON.parse(msg.payload); var devices = flow.get('devices') || {}; devices[data.deviceId] = { value: data.value, lastSeen: new Date().toISOString(), ip: msg.ip }; flow.set('devices', devices); msg.devices = devices; return msg;
✅ 解答例フロー
[ {"id": "ex3_tab", "type": "tab", "label": "演習3"}, {"id": "ex3_udp_in", "type": "udp in", "z": "ex3_tab", "name": "UDP In :9002", "iface": "", "port": "9002", "ipv": "udp4", "multicast": "false", "group": "", "datatype": "utf8", "x": 170, "y": 100, "wires": [["ex3_func"]]}, {"id": "ex3_func", "type": "function", "z": "ex3_tab", "name": "データ集約", "func": "try {\n var data = JSON.parse(msg.payload);\n var devices = flow.get('devices') || {};\n \n devices[data.deviceId] = {\n value: data.value,\n lastSeen: new Date().toISOString(),\n ip: msg.ip\n };\n \n flow.set('devices', devices);\n msg.devices = devices;\n \n node.status({fill: \"green\", shape: \"dot\", text: Object.keys(devices).length + \" devices\"});\n} catch(e) {\n msg.error = e.message;\n node.status({fill: \"red\", shape: \"ring\", text: \"Error\"});\n}\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 370, "y": 100, "wires": [["ex3_debug"]]}, {"id": "ex3_debug", "type": "debug", "z": "ex3_tab", "name": "デバイス一覧", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "devices", "targetType": "msg", "x": 570, "y": 100, "wires": []}, {"id": "ex3_inject1", "type": "inject", "z": "ex3_tab", "name": "dev-001", "props": [{"p": "payload"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "{\"deviceId\":\"dev-001\",\"value\":25}", "payloadType": "str", "x": 160, "y": 200, "wires": [["ex3_udp_out"]]}, {"id": "ex3_inject2", "type": "inject", "z": "ex3_tab", "name": "dev-002", "props": [{"p": "payload"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "{\"deviceId\":\"dev-002\",\"value\":30}", "payloadType": "str", "x": 160, "y": 240, "wires": [["ex3_udp_out"]]}, {"id": "ex3_udp_out", "type": "udp out", "z": "ex3_tab", "name": "UDP Out", "addr": "localhost", "iface": "", "port": "9002", "ipv": "udp4", "outport": "", "base64": false, "multicast": "false", "x": 360, "y": 220, "wires": []} ]

演習4: ブロードキャストによるデバイス発見 上級

📋 課題: 「DISCOVER」ブロードキャストを送信し、応答したデバイスを一覧表示するシステムを作成してください。

🎯 要求仕様:

✅ 成功の条件:

💡 ヒント

「発見側」と「デバイス側」両方の機能を同一フローに実装します。

デバイス側: 受信データが「DISCOVER」なら自デバイス情報を返信

発見側: 応答(DISCOVER以外)を収集してリスト化

✅ 解答例フロー
[ {"id": "ex4_tab", "type": "tab", "label": "演習4"}, {"id": "ex4_comment1", "type": "comment", "z": "ex4_tab", "name": "【発見リクエスト送信】", "info": "", "x": 170, "y": 40, "wires": []}, {"id": "ex4_inject_discover", "type": "inject", "z": "ex4_tab", "name": "DISCOVER送信", "props": [{"p": "payload"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "DISCOVER", "payloadType": "str", "x": 180, "y": 100, "wires": [["ex4_func_clear", "ex4_udp_broadcast"]]}, {"id": "ex4_func_clear", "type": "function", "z": "ex4_tab", "name": "リストクリア", "func": "flow.set('discoveredDevices', {});\nreturn null;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 390, "y": 100, "wires": [[]]}, {"id": "ex4_udp_broadcast", "type": "udp out", "z": "ex4_tab", "name": "Broadcast :9003", "addr": "255.255.255.255", "iface": "", "port": "9003", "ipv": "udp4", "outport": "", "base64": false, "multicast": "broadcast", "x": 400, "y": 140, "wires": []}, {"id": "ex4_comment2", "type": "comment", "z": "ex4_tab", "name": "【デバイス側(応答)】", "info": "", "x": 160, "y": 200, "wires": []}, {"id": "ex4_udp_in", "type": "udp in", "z": "ex4_tab", "name": "UDP In :9003", "iface": "", "port": "9003", "ipv": "udp4", "multicast": "false", "group": "", "datatype": "utf8", "x": 170, "y": 260, "wires": [["ex4_switch"]]}, {"id": "ex4_switch", "type": "switch", "z": "ex4_tab", "name": "DISCOVER判定", "property": "payload", "propertyType": "msg", "rules": [{"t": "eq", "v": "DISCOVER", "vt": "str"}, {"t": "else"}], "checkall": "false", "repair": false, "outputs": 2, "x": 380, "y": 260, "wires": [["ex4_func_response"], ["ex4_func_collect"]]}, {"id": "ex4_func_response", "type": "function", "z": "ex4_tab", "name": "デバイス情報返信", "func": "// デバイス情報を作成\nvar deviceInfo = JSON.stringify({\n type: \"DEVICE_INFO\",\n deviceId: \"my-device-\" + Math.floor(Math.random() * 1000),\n name: \"Node-RED Device\",\n timestamp: new Date().toISOString()\n});\n\nmsg.payload = deviceInfo;\n// msg.ip と msg.port は保持されている\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 620, "y": 240, "wires": [["ex4_udp_reply"]]}, {"id": "ex4_udp_reply", "type": "udp out", "z": "ex4_tab", "name": "Reply", "addr": "", "iface": "", "port": "", "ipv": "udp4", "outport": "", "base64": false, "multicast": "false", "x": 810, "y": 240, "wires": []}, {"id": "ex4_func_collect", "type": "function", "z": "ex4_tab", "name": "応答収集", "func": "try {\n var data = JSON.parse(msg.payload);\n if (data.type === \"DEVICE_INFO\") {\n var devices = flow.get('discoveredDevices') || {};\n devices[data.deviceId] = {\n name: data.name,\n ip: msg.ip,\n timestamp: data.timestamp\n };\n flow.set('discoveredDevices', devices);\n msg.devices = devices;\n node.status({fill: \"green\", shape: \"dot\", text: Object.keys(devices).length + \" found\"});\n return msg;\n }\n} catch(e) {}\nreturn null;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 600, "y": 280, "wires": [["ex4_debug"]]}, {"id": "ex4_debug", "type": "debug", "z": "ex4_tab", "name": "発見デバイス", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "devices", "targetType": "msg", "x": 790, "y": 280, "wires": []} ]

✅ 7. まとめ

🎯 重要ポイント:

⚠️ 注意事項:

🔧 8. トラブルシューティング

症状原因解決方法
データが届かないファイアウォール/ポート未開放FW設定確認、別ポート試行
ブロードキャストが届かない異なるサブネット/ルーター越え同一サブネット内で使用
データが途中で切れるMTU超過データサイズを小さくする
文字化けエンコーディング不一致UTF-8で統一
返信が届かないmsg.ip/port が未設定受信時のmsg.ip/portを保持

🏭 9. 実務活用例

ケース1: センサーデータ収集

複数のIoTセンサーからUDPでデータを受信。多少のデータロスが許容できる場合に最適。

ケース2: デバイス発見(Discovery)

ネットワーク上のデバイスをブロードキャストで発見。mDNS/Bonjourと同様の機能を実装可能。

ケース3: リアルタイム通知

即時性が重要な通知システム。低レイテンシが求められる場合に有効。

ケース4: Raspberry Pi 間の軽量通信

同一ネットワーク内の複数Raspberry Piでセンサーデータを共有。

📚 Node-RED 公式ドキュメント - UDP

🏠