PR
この連載は、報道目的の実験を行い、その結果を掲載するものです。内容には十分注意をしていますが、記事内容を試すことは自己責任で行ってください。

 ここは、ネットワーク関連企業「BPネットワークス」が誇る本社の超高層タワービル…の地下3階、機械室の隣にある第二R&Dセンター。もうすぐ忘年会シーズンなのに、浮かない顔の片岡さん。

片岡:悪玉コレステロールに中性脂肪か(ふぅ)。

矢田:どうしたんですか?

片岡:健康診断の結果が…。

 そこへ吉田さんがやってきた。

吉田:はーい、みなさん。あれ、どうしたんですか、片岡さん?

矢田:さっきから、あの調子です。

吉田:あっ、この間の健康診断のせいね。また、結果が悪かったんでしょ。飲み過ぎ食べ過ぎは今に始まったことじゃないから、まずお仕事ね。今回は、工場のIoTをやっているP社からの依頼よ。

神崎:製造業のIoTって最近よく耳にしますね。

吉田:IoTって漠然とした夢物語が多いけど、製造業のIoTは生産現場のカイゼンや新たな製品やサービスの開発といった目的が明確だからね。

片岡:ふぅ。

吉田:片岡さん、聞いてる?

片岡:ん。で、P社の依頼とは?

吉田:P社が開発中の工場でのIoT案件なの。その工場には、複数の製造ラインがあって、そこに複数のセンサーを取り付けて、データを収集する計画なの(図1)。

図1●途中に低速の回線があるP社のIoTシステム
図1●途中に低速の回線があるP社のIoTシステム
広い工場内に敷設するLANでは伝送距離が100mを超えてしまい、通常のイーサネットが使えないことがよくある。途中で産業用VDSLモデムを使い既存のツイストぺアケーブルで数百mを超える通信をする場合、その帯域が数十Mビット/秒に制限されることがある。こうしたシステムで多数のIoT機器からの通信が集中しても問題が起こらないのだろうか。
[画像のクリックで拡大表示]

片岡:産業用VDSLモデムを使うのか(帯域が狭いな…)。

矢田:VDSLって、マンションとかの構内接続に使うモデムの?

吉田:そう、その産業用ね。

神崎:でも、VDSLだと帯域は数十Mビット/秒でしょ。今どき貧弱で遅すぎでは。

片岡:確かに、センサー端末の数が増えたときは不安だな。特に、トラフィックが混雑するときは。

吉田:そう思うでしょ。それでP社もHTTPを使う予定だったけど、ネットワークの混雑を見越してプロトコルにCoAPを使うことを考えているの。

矢田:CoAPか。以前実験したわね。UDPだからHTTPより軽くて速いはずだわ(図2)。

図2●HTTPとCoAPにおけるシーケンスの違い
図2●HTTPとCoAPにおけるシーケンスの違い
TCPを使うHTTPは最初に3ウエイハンドシェークでコネクションを確立してから、HTTPのGET/POSTメソッドを使ってデータを送ってコネクションを閉じるので何度もやり取りする必要がある。一方、UDPを使うCoAPはGET/POSTメソッドでデータを送って応答が戻るという単純なやり取りだ。
[画像のクリックで拡大表示]

吉田:でも、P社のプログラマーがCoAPは嫌だ、と言って聞かないらしいの。

矢田:そりゃ、プログラマーは使い慣れたHTTPが楽で安心だし。

吉田:それでP社から、貧弱な通信環境でIoT向け通信プロトコルがどこまで使えるかを調査してほしい、との依頼なの。特に、回線が混雑した場合のCoAPの優位性を示して、プログラマーを納得させる結果がほしいというのよ。

矢田:CoAPはHTTPより軽いプロトコルだから、回線が遅い場合は有利になるはずだわ。

吉田:それを実験で確かめるわけ。今回の依頼は、「貧弱な通信環境でIoT向け通信が使えるかを調査せよ!」よ。じゃ、お願いね。

 と、いつものように、用件だけを伝えると行ってしまった。

神崎:またまた面倒な案件を。

矢田:貧弱な通信環境といっても、帯域制御装置や遅い回線のシミュレーターなんてないし。

片岡:そうだ、倉庫で眠っている古いルーターを使おう!あれならシリアル回線で2台のルーター同士を接続できる

神崎:なるほど。シリアル回線接続で速度を落とすわけですね。

矢田:テストには、以前の実験で作ったRaspberry PiのWebIOPiを使う環境が流用できそうです。クライアント側でPythonのスクリプトを走らせて、HTTPまたはCoAPを使ってGPIOのデータを送信できます(図3)。

図3●今回の実験環境
図3●今回の実験環境
2台のルーター(アライドテレシスAR320)のシリアルインタフェース間をクロスケーブルで接続し、75~11万5200ビット/秒の間で低速回線環境を再現。WebIOPiで、クライアント側のRaspberry Piからサーバー側のRaspberry Piに向けてCoAPまたはHTTPを使って、GPIOの状態(0か1の1ビットの情報)を30秒に1回の頻度で通知する。
[画像のクリックで拡大表示]

片岡:ルーターの準備はOKだ。まずはシリアルで11万5200ビット/秒で接続した。ルーターのコマンドで速度を最低75ビット/秒まで落とせる。これで遅い回線をシミュレーションできるぞ。

矢田:Raspberry PiもOKです。

片岡:よし、実験環境は整った。まず回線の接続性を確認するために、各速度設定でpingでの疎通を試験してみよう。11万5200ビット/秒から、最低の75ビット/秒まで徐々に落としながら動作の確認だ。

 そうして実験した結果は表1の左側の列のようになった。

表1●実験1の結果
表1●実験1の結果
ルーター間のシリアル接続の設定速度を変えながら、ping応答時間やHTTP/CoAPでの接続性を計測した。
[画像のクリックで拡大表示]

片岡:さすがに、1200ビット/秒になると遅いな。デフォルトのpingで1秒もかかる。さらに、速度を落とすと…。

矢田:75ビット/秒でもping応答はあるわ。でも、遅っ。

神崎:応答に19秒なんてありえない。こんな狭い帯域では、きっと重たいHTTPどころか軽いCoAPでもダメでしょう。

片岡:そうだな。試してみよう。

 実験1では、スクリプトを使ってHTTPとCoAPの通信を実行しながら11万5200ビット/秒から75ビット/秒まで速度を徐々に落とす実験をした。CoAPに比べて重たいHTTPが先に不具合が発生するかと思われたが…。

矢田:あれ、CoAPに1200ビット/秒でエラーが出ました(図4左)。

図4●CoAPのやり取りでは1200ビット/秒の回線速度でエラーが発生した
図4●CoAPのやり取りでは1200ビット/秒の回線速度でエラーが発生した
サーバーはACK応答を返している。しかし、クライアント側に届くのが遅すぎて待ちきれずにクライアント側で相手とのCoAP通信が使えないと判断しているようだ。
[画像のクリックで拡大表示]

神崎:HTTPは問題ありません。

片岡:ん。何でだ?

 TCPを使うHTTPより、UDPを使う軽いCoAPのほうが遅い回線に強いと考えていた。だが、意外にもCoAPで先にエラーが出てしまった。

矢田:想定外の結果ですね。

片岡:そうだな。キャプチャーしたパケットを見てみよう(図4右)。おや、ICMPのエラーメッセージが出ているぞ。

矢田:クライアントからサーバーへ向けてCoAPが使えないと報告しているわ。

片岡:クライアントからCoAPを使ってデータを送る「POST要求」を受信したサーバーはACK応答を返しているが、回線が狭いからクライアントに届くのが遅すぎたのだろう。

矢田:1200ビット/秒のping応答が約1秒ですからね。

片岡:それでサーバーからの応答パケットを待ちきれないクライアントが同じPOST要求を何度も再送している。だけど、パケットを再送すると余計に回線の混雑がひどくなり、さらに応答が遅くなる。

神崎:悪循環だ。

片岡:応答が遅すぎた結果、クライアント側でタイムアウトが発生して、UDPのポート5683番は使えないと判断しているようだな

矢田:それで、アプリ(Pythonのスクリプト)でも「Exception: No data received」とエラーになったのね。

片岡:HTTPのパケットも調べてみよう。

矢田:1200ビット/秒の場合を見ると真っ黒け(図5)。

図5●HTTPを使った場合の通信パケット
図5●HTTPを使った場合の通信パケット
1200ビット/秒よりも通信速度が遅くなると、うまく送れずに再送を繰り返す。150ビット/秒になると、3ウエイハンドシェークに失敗してエラーになる。
[画像のクリックで拡大表示]

神崎:エラー多発だ。

矢田:TCPの悲鳴が聞こえそう。何度も再送を繰り返し、どうにか頑張って伝送しているって感じね。

片岡:続いて、600ビット/秒のHTTPも見てみよう。

神崎:300ビット/秒…まだ頑張っている。150ビット/秒…さすがにNGか。RSTパケットが出ています。

矢田:うわ、さらに画面が黒い。もはや、3ウエイハンドシェークができないわね。

神崎:pingの応答が約9秒もかかる環境ですからね。3ウエイハンドシェークの段階で再送ばかり。そしてRSTパケットで強制終了。

矢田:TCPコネクションそのものが確立できません。

神崎:でも、HTTPがCoAPより遅い回線で使えたのは意外ですね。

片岡:これは、CoAPやHTTPのプロトコルの特性というより、アプリ側でのUDPの使い方の問題じゃないかな。今回使用したWebIOPiでUDPのチューニングをしないとダメだろうな。

矢田:言い換えると「CoAPの実力を発揮できない」ともいえますね。どうにか試験できないかな?

神崎:そうだ。CoAPを使う場合、はじめにGPIOを初期化する要求を出して、そのACKを受信したら、すぐに2番目のGPIOのデータを送る要求を出していますよね。

片岡:そうだな、最初だけ連続して送信して、それがうまくいくと以降は30秒ごとに1パケットを送るゆっくりとした送信になる。

神崎:最初に送信が連続するから1200ビット/秒では回線が混雑し、再送パケットでさらに混雑し…の悪循環になるのでは?

矢田:要求パケットを2個連続して送信するのは最初だけ。そうか。最初さえクリアできたらCoAPでも通信できる可能性があるわね。

片岡:そうだな。

神崎:初期化で引っかかるなら最初だけ速い設定でスプリクトを走らせて、正常に接続してから徐々に速度を落とすのはどうですか。

片岡:なるほど。実際の運用でも、大きなトラブルなどが発生した場合は数多くのIoT端末から一斉にデータが届いて極端に厳しい状況になり得るだろうが、通常時はもっと余裕があるはずだ。そう考えると、最初は高速で接続してから速度を落としたほうが、実際にあり得る状況に近いといえるな。じゃ、それを実験2としてやってみよう。

 実験2では最初に1200ビット/秒でクライアント側でスクリプトを動作させてサーバーに接続してから、ルーターのコマンドを使って徐々に速度を落としていった(表2)。

表2●実験2の結果
表2●実験2の結果
11万5200ビット/秒で接続した後にHTTPまたはCoAPのスクリプトを実行してから、速度を徐々に下げていくと、75ビット/秒という超低速でもCoAPで通信できた。
[画像のクリックで拡大表示]

神崎:スゲー。75ビット/秒でもCoAPが頑張っている(図6)。

図6●実験2でCoAPを使った場合にやり取りしたパケット
図6●実験2でCoAPを使った場合にやり取りしたパケット
75ビット/秒まで通信速度を落としても、データの送信に成功している。
[画像のクリックで拡大表示]

矢田:TCPは、実験2でも300ビット/秒から150ビット/秒への移行後にエラーになるわね。

神崎:やっぱりTCPのコネクションを確立できなくなってくる。

片岡:帯域が狭くなると、CoAPが有利なようだな。

 そこへ吉田さんが再登場。

吉田:実験どうなった?

矢田:これこれこうで…。

神崎:やはり、極端な回線混雑時にはCoAPが強そうね。

矢田:でも、HTTPも300ビット/秒まで頑張りましたよ。

片岡:とはいえ、再送パケットを乱発して必要以上のパケットを送出することになり、ほかに大きな迷惑をかける可能性が高いぞ。

神崎:センサーの端末数が多い環境で同じ状況になると、再送パケットの嵐になりそうですね。

片岡:もし従量課金なら、すごく無駄な料金が発生する。

矢田:通信速度が遅くて貧弱な回線の場合、CoAPが有利なのね。

片岡:極端に遅い場合は、UDPを使うアプリのチューニングも必要だが、やはりCoAPが適しているといえるな。

吉田:では、センター長からのメッセージよ。「諸君、実験ご苦労だった。IoTシステムの場合、通常のTCP/IPの通信とは異なり、十分な回線帯域を確保できないケースがある。そのときは、無理をして末端の端末までIPを使うのではなく、他のプロトコルを活用することも大切だ。以上」。

矢田:IPだけじゃダメ、ということか。

吉田:最近話題のLPWAを使ったIoTシステムでも、サーバーとゲートウエイ間はIPを使うけど、ゲートウエイとIoT端末の間は、それぞれ固有のレイヤー2のプロトコルで通信することが多いわ。要は、適材適所のプロトコルを選択することが重要ね。

片岡:で、実験も終わったし、もうすぐ定時だし…一杯行くか。

神崎矢田いいですね。

吉田:でも、片岡さんは、アルコールと脂っこいもの抜きよ!

片岡:そりゃないぞー。

吉田:血管が詰まっても知らないわよ。

片岡:…(トホホ)。

▼IoT
Internet of Thingsの略。
▼VDSL
Very high bit rate Digital Subscriber Lineの略。既存の電話回線を利用して下り100Mビット/秒、上り最大40Mビット/秒の通信を実現する。
▼トラフィックが混雑するとき
工場全体に波及する大きなトラブルが発生すると、ほぼすべてのセンサー端末が一斉に異常を検知してサーバーへ通知する可能性がある。そうなると、大量のトラフィックが発生する。例えば、電源の一時的な停止(瞬断)や、地震などの災害が考えられる。
▼CoAP
Constrained Application Protocolの略。標準化団体のIETF(Internet Engineering Task Force)で標準化策定が進むIoT向けのプロトコル。UDPを使い、ヘッダーサイズが4バイトの軽いプロトコル。Constrainedには「制約がある」や「強いられて窮屈な」といった意味がある。
▼以前実験した
2006年4月号の本連載でCoAPの通信を調査した。
▼シリアル回線
本来は、ルーターにパソコンなどのコンソールを接続するものである。
▼接続できる
今回使用したアライドテレシスAR320は、シリアルポート(ASYN)が2ポートあり、シリアルを使ってルーター間の接続もできる仕様だ。本来は、ISDNのターミナルアダプターやモデムによるバックアップ用の接続に使う。
▼WebIOPi
Raspberry Pi用のIoTフレームワーク。Pythonのスクリプト(プログラム)から、WebIOPiのAPIを呼び出すことにより、GPIOのデータを送信できる。使用するアプリケーション層のプロトコルには、HTTPやCoAPを指定できる。
▼GPIO
General-Purpose Input/Outputの略。Raspberry Piのようなマイコンが外部と接続するために用意している汎用入出力インタフェースのこと。
▼デフォルトのping
32バイトのダミーデータを転送する。ICMPヘッダーが8バイト、IPヘッダーが20バイト、イーサネットのヘッダーが14バイト、エラー訂正のFCS(Frame Check Sequence)4バイトを加えた合計78バイト長となる。
▼TCP
Transmission Control Protocolの略。
▼UDP
User Datagram Protocolの略。TCPと違い、パケットが到達したことを確認しないので、TCPに比べて軽い。
▼POST要求
図2に示したようにHTTPとCoAPのどちらもGETやPOSTといったメソッドを使ってデータを送受信する。
▼ACK
ACKnowledgementの略。
▼判断しているようだな
今回使用したWebIOPiの実装依存だと思われる。
▼RSTパケット
RSTはReSeTの略で、TCPでの接続を中断・拒否する際に送るパケット。
▼3ウエイハンドシェーク
TCPで、実際にデータを送信する前に相手にデータが届く状態か確かめる手順。最初に送信側から相手に「SYN」(SYNchronize)というパケットを送る。そのパケットを受け取った受信側は、確認を示すACK(ACKnowledgement)とSYNとを合わせた「SYN+ACK」パケットを送信側に返す。そのパケットを受信した送信側が「ACK」パケットを送ることで、データを送信するコネクションが確立される。
▼アプリのチューニング
実験1でも発生したようにUDPを使うCoAPでは、回線速度が遅くなるとアプリケーション側でエラーとなる可能性がある。これを回避するにはアプリ側でUDPの応答のタイムアウトのチューニングなどが必要と考えられる。
▼LPWA
Low Power Wide Areaの略。IoTのインフラとして注目されている無線通信技術。少ない消費電力で、数k~数十kmといった遠い距離での通信を実現する。
今回のまとめ

●TCPを使うHTTPでも、利用する端末の台数が少なければ意外と低速度な通信環境でも十分にデータを送れる可能性がある。
●帯域の狭い通信環境でIoTを利用する場合は、パケットの再送などが多発する可能性の高いHTTPよりオーバーヘッドの少ないCoAPのほうが適している。