TCP/IP通信の使用

イントロダクション

Aurora Vision Studioには、TCP/IPプロトコルを使用した通信のための一連のフィルタがあります。これらはToolboxのProgram I\Oカテゴリに配置されています。

TCP/IPは実際にはTCPIPの上にあるプロトコルスタックです。 これらのプロトコルは、ローカルから広域ネットワークまで普遍的に使用され、インターネット上の通信には欠かせません。 また、他のプロトコルの基礎となっており、HTTP、FTP、および産業用のModbus TCP/IPやModbus RTU/IPなどもこれに基づいています。

TCP/IPプロトコルは、トランスポートレベルの通信プロトコルです。 これは双方向の生データストリームを提供し、接続リンクを維持し、データの整合性を保ちます(データの順序を保ち、失われたネットワークパケットを再送信しようとします)。 ただし、具体的な状況に対して安全で安定した長期通信を実現するには通常、生のTCP/IPプロトコルだけでは十分ではなく、特定のシステム用に設計された追加の通信プロトコルが必要です。 たとえば、正しいコマンドの実行を確認するマスター-スレーブコマンドシステムを実装する場合、コマンドとアクノリッジのトランザクションを使用する必要があります(まずコマンドを送信し、次にコマンドアクノリッジをタイムアウト付きで受信し、タイムアウトが切れるとコマンドが正しく処理されなかったことを知らせます)。 単一の送信操作では、データが受信者によって正しく受信および処理されたかどうかを検出することはできません。なぜなら、それは単にデータを転送バッファに入れているだけだからです。 他の状況では異なるアプローチが必要であり、通常は接続先のシステムによって必要なプロトコルが課せられます。 これらの理由から、TCP/IPをベースにしたシステムを適切に実装するには、TCP/IPおよび通信プロトコルの基本的な知識が必要です。

通信はソケットを使用して実現されます。 ネットワークソケットは、接続の双方向エンドポイントの抽象的な概念です。 ソケットには書き込みまたは読み取りができます。接続の一方の端に書き込まれたデータは、対向の端から読み取ることができます。 ソケットのメカニズムは多くのプログラミング言語で見られ、Aurora Vision Studioでは一般的なネットワークプログラミングのツールとなっています。

TCP/IPプロトコルスタックを使用して通信するには、まず接続を確立する必要があります。これには2つの方法があります:(1)サーバーへの接続を開始し、(2)クライアントからの接続を受け入れます。両方の方法で生成されるソケットは後で区別できません。同じように動作し、双方向通信ユーティリティとして振る舞います。

一度作成された接続は、そのソケットを介してアクセスされます。返されたソケットは、その後のすべてのデータの書き込みと読み取り、および切断に使用されるため、これらのフィルタに接続する必要があります。

通常、接続はアプリケーションがメインループに入る前に作成され、プロセスの複数の反復を通じて有効なままです。明示的に閉じられるかI/Oエラーが発生したときに無効になります。

TcpIp_Connect 特定のリモートホストのポートに接続します。
この操作を実行するのはクライアントです。
TcpIp_Accept ローカルTCPポートを開き、着信接続を待機します。
この操作を実行するのはサーバーです。

ソケットへのデータの書き込み

データを送信するためのフィルタはSocketId値を受け取り、オープンされた接続を識別し、他のエンドポイントに転送するデータを指定します。データにはテキスト、バイナリ、または直列化されたオブジェクトの3つの異なる種類があります。

書き込み操作は通常高速ですが、他の側がデータを消費するのが遅い場合や、ネットワークのスループットよりも速くデータを書き込もうとする場合など、問題が発生する可能性があります。書き込み操作は、データの配信または受信確認を待たずにデータを転送バッファに格納することに制限されます。 データが受信者によってデリバリーまたは処理される速さよりも速く書き込まれると、転送バッファに保持されるデータの量が増え始め、通信にかなりの遅延が発生し、最終的には転送バッファがオーバーフローし、書き込み操作がエラーを引き起こします。

TcpIp_WriteText UTF-8エンコーディングでプレーンテキストをソケットに書き込みます。
オプションでテキストにサフィックス*を追加することができます。
TcpIp_WriteBuffer ByteBufferとして指定された任意のバイナリデータをソケットに書き込みます。
TcpIp_WriteObject 直列化されたオブジェクトをソケットに書き込みます。生成されたデータは、以下で説明されているTcpIp_ReadObjectフィルタを使用してのみ、同じ具現タイプを使用して読むことができます。

ソケットからのデータの読み取り

データの読み取りにはオープンな接続が必要で、受信したデータは次のいずれかの方法で返される可能性があります:

  • Stringとして、UTF-8エンコーディングを使用
  • ByteBufferとして
  • 逆シリアル化されたオブジェクトとして

データを受信するために必要な時間は、ネットワークのラウンドトリップタイム(RTT)、転送帯域幅、受信データの量に依存することがありますが、それよりもはるかに重要なのは、接続の反対側がデータを送信しているかどうかです。データが読み取り可能でない場合、フィルタはそれが到着するのを待たなければなりません。これは、inTimeoutパラメータの使用が最も意味がある場所です。

読み取り用のフィルタは、オプションで接続が反対側で閉じられ、これ以上データを取得できないことを通知することがあります。このメカニズムは、接続の終了が送信または通信の終了を示すために使用される場合があります。 outEof出力は、この状態を示すために使用されます。ストリームの終了が示されると、ソケットはまだ有効であり、引き続き閉じる必要があります。

TcpIp_ReadLine 指定された区切り文字に達するまでUTF-8エンコーディングでテキストを読み取ります。
区切り文字*は、破棄されるか、出力の最後に返されるか、またはバッファに残され、後続の読み取り操作で処理される可能性があります。
TcpIp_ReadBuffer 固定長のバイナリデータを読み取ります。
TcpIp_ReadObject 直列化されたオブジェクトを読み取ります。 データは、上述のTcpIp_WriteObjectフィルタを使用して同じ型パラメータを使用して実行されているAurora Vision Studio/Executorの別のインスタンスからのみ取得できます。
TcpIp_ReadAllText EOFまで(接続が閉じられるまで)すべてのテキストを読み取ります。
TcpIp_ReadAllBuffer EOFまで(接続が閉じられるまで)すべてのデータを読み取ります。

* - デリミタとサフィックスは、エスケープされた文字列として渡されます。これらは、エスケープシーケンスと呼ばれる特別な意味を持つ文字の組み合わせを可能にする特別な文字列です。最も重要なのは "\n"(改行)、"\r"(キャリッジリターン)、および "\\"(逐語的なバックスラッシュ)です。これにより、Stringに簡単に含めることができない特定の文字を送受信できます。

使用後の接続の閉じる

もはや必要ない場合、対応するソケットはソケット閉じるフィルタに渡され、基礎となる接続を閉じ、関連するシステムリソースを解放します。すべてのソケットは、接続が他方で閉じられたか、接続が切断された場合でも、ソケット閉じるフィルタを使用して明示的に閉じる必要があります。

通常、接続はアプリケーションがメインのループマクロフィルタを終了した後に閉じられます。

TcpIp_Close 接続を正常に閉じてソケットを解放します。

アプリケーションの構造

最も一般的なアプリケーション構造は、次の3つの要素で構成されています:

  1. ソケットを作成するフィルタ(TcpIp_ConnectまたはTcpIp_Accept)の実行。
  2. プログラム(タスク)のメインループを実現するマクロフィルタ。
  3. ソケットを閉じるフィルタ(TcpIp_Close)。

メインループのタスクが次のセクションで説明するように I/O エラーによって終了する可能性がある場合は、再接続を試み、再びメインループに入るように保証するために、四番目の要素も必要です。これは Loop フィルタ(おそらくいくつかの Delay と一緒に)です。

詳細については、「IO Simple TcpIp Communication」の公式例を参照してください。

エラーの処理と回復

エラー検出が重要なシステムでは、通信の正確性チェックを、使用される通信プロトコルおよび通信ピアの機能に基づいて明示的に実装することが通常必要です。このようなチェックは通常、操作の確認メッセージの送信および制限された時間内に期待される転送の受信から構成されます。これを実装するには、受信フィルタのタイムアウトシステムが使用されます。

さらに、すべての TCP/IP フィルタは、予期しない状況や内部通信エラーについて IoError を発生させることができます。 このようなエラーは、ピアによる接続の切断(特定のフィルタで期待されていない場合)、システムエラー、ネットワークエラー、または 切断された接続の状態などから発生する可能性があります。切断された接続は通常、通信エラーの最も一般的な原因です。接続は切断された状態に入る のは、基盤となるシステムが通信の相手がデータを受信していないことを確認していないと検出した場合です(一部の システムで定義された時間内)。システムが接続を切断状態としてマークした後、次の TCP/IP フィルタ(この接続を使用しようとする) は IoError を発生させることでそれについて通知します。切断された接続を検出することに依存することは、通常、エラークリティカルなシステムで有効な接続を確認する最も信頼性の低い方法ではありません。検出には時間がかかる可能性があり、検出時間は異なるシステムで異なり、 いくつかの状況では(単方向の伝送など)検出されないことがあります。TCP/IP Keep-Alive メカニズム(TcpIp_Connect および TcpIp_Accept でアクティブにできる)は、切断された接続を検出する確率を高めるのに役立つかもしれません。

フィルタによって発生した IoError は、マクロフィルタ エラー処理 メカニズムを使用して処理できます(TCP/IP フィルタを別の タスク に配置することで)。TCP/IP フィルタがエラーで終了すると、その基本となる接続は未定義の状態になり、接続はもはや使用しないでください。そして、ソケットは TcpIp_Close フィルタで閉じる必要があります。アプリケーションはその後、TCP/IP エラーから回復しようとすることができます。通信エラーからの回復の具体的な可能性と要件は、使用されるプロトコルと通信ピアの機能に依存します。

XML ファイルを使用した Tcp/Ip 通信

Tcp/Ip 通信で情報をやり取りする場合、通常は XML ドキュメントとして構造化された情報が使用されます。 この種の通信では、テキストの読み書き用のフィルタと、XML ツリーの解析または作成のための System :: XML カテゴリのフィルタを一緒に使用します。

例: HTTP からデータを読み取る

Simple download from HTTP

HTTP を介して画像をダウンロードするためのフィルタのシーケンス

この例は、次の手順で構成されています:

  1. 指定されたホストwww.adaptive-vision.comのポート80(HTTPの標準ポート)に接続します。
  2. 特定のURLから画像を要求するためにHTTPクエリ文字列を送信します。
  3. "\r\n\r\n"(ダブルニューライン)で終わるヘッダを読み取ります(処理はされません)。
  4. 残りのすべてのデータ - HTTPの応答ボディ - を読み取り、バイナリデータとして返します。
  5. ユーティリティ関数を使用して、バイトを画像に変換します。