Skip to main content

This is documentation for Caché & Ensemble. See the InterSystems IRIS version of this content.Opens in a new tab

For information on migrating to InterSystems IRISOpens in a new tab, see Why Migrate to InterSystems IRIS?

TCP クライアント/サーバ通信

この章では、TCP/IP を使用した Caché プロセス間のリモート通信の設定方法について説明します。パイプ、またはインタジョブ・コミュニケーション (IJC) デバイスを使用したプロセス間のローカル通信については、このドキュメントの "ローカル・プロセス間通信" の章を参照してください。

Caché は、TCP および UDP の 2 つのインターネット・プロトコル (IP) をサポートします。これらのインターネット・プロトコルにより、Caché は、プロセスが Caché を実行中かどうかにかかわらず、ローカルあるいはリモート・システムでプロセス通信できます。

  • TCP : Caché は、転送制御プロトコル (TCP) バインディングをサポートします。サーバと 1 つのクライアント間の双方向通信を確立します。エラーのチェックと修正を伴った信頼性のあるデータのバイト・ストリーム送信、およびメッセージ応答を提供します。

  • UDP: Caché は、ユーザ・データグラム・プロトコル (UDP) バインディングをサポートします。サーバと多数のクライアント間の双方向メッセージ転送を提供します。UDP は、接続ベースではありません。各データ・パケットの転送は独立したイベントになります。ローカル・パケット・ブロードキャストおよびリモート・マルチキャストにおいて高速で軽量なデータ転送を提供します。通常、TCP よりも信頼性が低くなっています。メッセージ応答を提供しません。詳細は、このドキュメントの "UDP クライアント/サーバ通信" の章を参照してください。

TCP バインディングの目的は、Caché を広範囲の標準ネットワークに接続させ、ユーザが入出力コマンドからネットワーク・プロトコルの基本的な機能を使用できるようにすることです。

TCP/IP プロトコルにより、システムは、異なるタイプのネットワーク・ハードウェアを使用している場合でも通信できます。例えば、インターネット経由の TCP では、Ethernet を使用するシステムと Token Ring を使用するシステム間でメッセージを送受信できます。TCP は、データ送信の精度を管理します。IP、つまりインターネット・プロトコルは、ネットワークあるいはインターネット上の異なるシステム間の実データ転送を実行します。

TCP バインディングを使用すると、クライアント/サーバ・システムのクライアント部とサーバ部の両方を生成できます。分散データベース・システムのクライアント/サーバでは、1 つあるいは複数のクライアント・システムのユーザは、別のシステム、つまりサーバ上のデータベースに格納された情報を処理できます。

TCP 接続の概要

システム間のクライアント/サーバ・リレーションシップを生成するには、以下の規則に従う必要があります。

  • システムは、TCP/IPプロトコル・ソフトウェアを含め、適切なネットワーク・ハードウェアとソフトウェアに接続されている必要があります。

  • システムは、TCP ポートを経由して相互通信します。接続の両端にあるプロセスは、同じポート番号を使用する必要があります。

  • Caché の OPENUSE、および CLOSE の各コマンドでは、TCP ポート番号あるいは TCP ポート番号を示す devicename のいずれかをデバイスとして指定します。

これらの規則を使用して、TCP バインディング接続を構築します。以下は、一般的な手順です。

  1. サーバ・プロセスは、TCP デバイスに OPEN コマンドを発行します。

  2. サーバ・プロセスは、USE コマンドを発行し、その後に READ コマンドを発行し、クライアント・プロセスからの入力を待機します。サーバは、クライアントが接続を構築する前に、リッスン状態になる必要があります。クライアントが接続を開いてデータを送信すると、最初の READ コマンドは完了します。OPEN コマンドに “A” モード・パラメータを指定すると、サーバに接続したとき、すぐに最初の READ が完了します。

  3. クライアント・プロセスは、接続中の TCP デバイスを指定する OPEN コマンドを発行します。

  4. クライアント・プロセスは、USE コマンド、その後 WRITE コマンドを発行して、接続を完了します。Caché は、WRITE コマンドのすべての文字をバッファにコピーします。WRITE ! あるいは WRITE # コマンドを発行してバッファをフラッシュした後、ネットワークに書き込みます。

  5. 最初の WRITE コマンドでクライアントが送信した文字をサーバが読み取った後は、サーバとクライアントの両方で継続して READ コマンドと WRITE コマンドを発行できます。同じポートでは、これらのコマンドの順番に制約はありません。

  6. どちら側からでも、CLOSE コマンドまたは HALT コマンドで接続を切断できます。最初にクライアント側を閉じることをお勧めします。別のクライアント・プロセスからの接続を受け入れることができるよう、サーバとの接続を切断する必要がある場合は、代わりに WRITE *-2 コマンド、または従来のバージョンと互換性のある、“DISCONNECT” オプションを指定した USE コマンドを発行し、それに READ コマンドを続けます。

Note:

この手順では、クライアントとサーバの両方が Caché プロセスであると想定しています (実際の環境では、いずれかのプロセスが Caché プロセスではないことがあります)。

以下のセクションは、Caché 入出力コマンドを使用して、クライアントとサーバ・プロセスの間に TCP バインディングを生成する方法を説明しています。

TCP デバイスの OPEN コマンド

サーバ・プロセスとクライアント・プロセスの両方が、ObjectScript の OPEN コマンドを使用して接続を開始します。サーバは、READ コマンドを発行して接続を完了し、クライアントの OPEN コマンドと最初のデータ転送を受け取ります。

Note:

既に開いている TCP デバイスで、OPEN コマンドを発行すると、この 2 番目の OPEN コマンドは USE コマンドとして扱われます。つまり、hostname および port パラメータは無視され (最初の OPEN コマンドの値は保持)、mode および terminators パラメータが更新されます。

OPEN コマンドの使用法

OPEN コマンドにより、使用する TCP バインディング・デバイスを確保します。構文は、以下のとおりです。

OPEN devicename:parameters:timeout:mnespace

以下はその説明です。

devicename フォーム |TCP| の後ろにいくつかの数字を持つ文字列です。デバイス名の数字部分は、デバイス識別子といいます。ポート番号が OPEN の parameters で指定されていない場合は、このデバイス識別子は一意の 5 桁の TCP ポート番号である必要があります。OPEN のパラメータでポート番号を指定している場合は (指定することをお勧めします)、1 つのジョブで使用するすべての TCP デバイス名が識別できる限り、このデバイス識別子には任意の一意の番号 (最大 2147483647) を指定できます。
parameters

オプション — 括弧で囲み、コロン (:) で区切ったデバイス・パラメータを 1 つ以上列記したものです。パラメータを省略する場合は、そのパラメータに該当する位置にコロン区切り文字を記述します (サーバ側で実行する OPEN コマンドでは、最初のパラメータは必ず省略することになります)。具体的なパラメータについては、以下で説明します。

最初のパラメータ (hostname) のみ指定する場合は、括弧を省略できます例えば、クライアント側で開く操作は OPEN "|TCP|7000":"127.0.0.1":10 となります。パラメータをまったく指定しない場合は括弧を省略できますが、区切り文字のコロンは記述する必要があります。例えば、サーバ側で開く操作は OPEN "|TCP|7000"::10 となります。

timeout オプション — Caché が TCP デバイスを開こうとする最大秒数です。この間にファイルを開くことができない場合、$TEST を 0 に設定し、制御をプロセスに戻します。成功した場合、$TEST を 1 に設定します。クライアントからの Open コマンドにタイムアウトを組み込むと、サーバが別のクライアントと通信中に接続を試行した場合に、クライアント・システムが停止することを防ぎます。サーバで一度に開くことができる接続は 1 つのみです。
mnespace オプション — ObjectScript のすべての OPEN コマンドで、そのままサポートされます。TCP バインディング向けに、事前に定義されたニーモニック空間はありません。

OPEN 引数を省略する場合は、コロン区切り文字を指定することで、引数が省略されていることを表現できます。

timeout 引数は、オプションですが、強くお勧めします。これは、OPEN の成功または失敗が、$TEST 特殊変数の値によって示され、$TEST は、timeout を指定した場合のみ設定されるためです。$TEST は、時間内にオープンが成功すると 1 に設定されます。時間が切れると、$TEST は 0 に設定されます。

WIndows システムで TCP 接続の試行が失敗すると、TCP 接続エラーが Caché システムのエラー・ログに書き込まれます ("Caché 監視ガイド" の “管理ポータルを使用した Caché の監視” の章の "Caché システム・エラー・ログ" を参照)。例えば、エラー・コード 10061 = WSAECONNREFUSED などが記録されます。

クライアント側の OPEN の例を以下に示します。この例の、7000 はポート番号です。また、"127.0.0.1" は parameters 引数 (IPv4 アドレス形式で指定した hostname) です。

  SET dev="|TCP|7000"
  OPEN dev:("127.0.0.1":7000)

hostname パラメータ

hostname パラメータは、クライアント側の OPEN には必須になります。クライアント側の parameters 引数は、単独の hostname になるか、hostname と、それに続くコンマ区切りのパラメータになります。hostname パラメータを単独で指定する場合は、parameters の括弧を省略できます。

サーバ側の parameters 引数では、hostname を省略します。

hostname は、IP ホストの名前 (リモート・ホストのローカル・システム・データベースから取得) になるか、IPv4 または IPv6 プロトコル形式の IP アドレスになります。これらのプロトコルは互換性がないため、サーバとクライアントの両方ともが同じインターネット・プロトコルを使用しない場合には転送が失敗します。

IPv4 アドレスは以下の形式です。n は、0 から 255 の範囲の 10 進数の整数です。

n.n.n.n

IPv6 アドレスは以下の完全な形式です。h は、4 桁の16 進数の数値です。

h:h:h:h:h:h:h:h

通常、IPv6 アドレスは先頭ゼロを削除してゼロの連続したセクションを二重コロン (::) に置き換えることによって省略されます。IPv6 アドレスで使用される二重コロンは 1 つのみです。IPv4 の省略ルールを使用すると、IPv6 ループバック・アドレスを "::1" として指定できます (これは、最初から 7 番目までの連続する h のセクションの値が 0000 であり、8 番目のセクションの先行するゼロが削除されていることを表しています)。

IPv4 および IPv6 の形式に関する詳細は、"Caché プログラミング入門ガイド" の “サーバ構成オプション” の章にある “IPv6 アドレスの使用” のセクションを参照してください。

サポートされるパラメータ

parameters 引数の書式は、以下のいずれかになります。

hostname
(hostname{:port{:mode{:terminators{:ibufsiz{:obufsiz{:queuesize{:keepalivetime}}}}}}})

parameters 引数に含まれるパラメータは、以下のとおりです。

パラメータ 意味
hostname オプション — IP ホストの名前、IPv4 プロトコル形式の IP アドレス、または IPv6 プロトコル形式の IP アドレスのいずれかです。引用符で囲んだ文字列で指定します。hostname は、クライアント側の OPEN には必須です。サーバ側の OPEN では省略します (プレースホルダのコロンで省略を表します)。
port オプション — 存在する場合、接続に使用する TCP ポート番号です。ポート番号が NULL もしくは省略されている場合、ポート番号は devicename の数値部から取得します。このパラメータは、10 進数のポート番号、またはサービス名のいずれかです。これは、ローカル・システムの TCP サービス名リゾルバに送信されます。
mode オプション — 引用符で囲んだ文字コードの文字列です。文字コードは、任意の順序で指定できます。Caché では、パラメータが左から右の順に実行されるので、パラメータ間の相互関係により優先の順序が決まる場合もあります。既定は、パケット・モードです。mode 文字列は、以下の文字 1 つ以上で構成します。
  • A — 受け入れモード。A がオンの場合、サーバの最初の読み取りは、クライアント・ジョブからの接続を受け入れるとすぐに、長さゼロの文字列を読み取って終了します。A がオフの場合、タイムアウトになるかデータが入手可能になるかのいずれかになるまで読み取りがブロックされます。

  • C — 以下の "キャリッジ・リターン・モード" を参照してください。

  • D — 以下の "切断の監視モード" を参照してください。

  • E — 以下の "エスケープ・シーケンス処理モード" を参照してください。

  • G — port パラメータは、既に開いているデータ・ソケットのソケット記述子として解釈されます。

  • M — ストリーム・モードの標準 Caché デバイス。このモードは、“PSTE” のオプション一式を呼び出す省略表現です。デバイスが双方向に任意のデータ行を渡すように振る舞う、標準 Caché デバイスのように動作します。バッファの制限を超えずに、あらゆる文字列のシーケンスを送受信できるよう、ストリーム・モードにします。出力には改行が追加され、入力からは改行が削除されます。READ コマンドは、ターミネータ文字が検出されるまで、タイムアウトになるまで、または指定された読み取り長さが読み取られるまでブロックされます。

  • P — レコード・ターミネータ文字で出力を埋め込みます。このモードを設定すると、WRITE ! では LF (改行)、WRITE # では FF (改ページ) が送信されます。さらに、書き込みバッファがフラッシュされます。WRITE *-3 コマンドを使用すると、データ・ストリームに文字を挿入することなく、バッファされたデータの送信を開始できます。WRITE *-3 は、ターミネータ文字を送信せずに書き込みバッファをフラッシュするため、データが完了したことを受信プログラムに通知しません。WRITE *-3 は、ターミネータを必要としない待機 (W) モードでより一般的に使用されます。

  • Q — 以下の "即時送信モード" を参照してください。

  • S — 以下の "ストリーム・モード" を参照してください。

  • T — 入力用標準ターミネータ。これを設定すると、CR、LF、および FF の各制御文字が読み取りターミネータとして機能します。

  • W — 待機モードです。このモードでは、WRITE !WRITE # コマンドによって、TCP デバイスでネットワーク出力バッファがフラッシュされることはありません。待機モードでは、次の WRITE *-3 コマンドがバッファをフラッシュし、データを送信するまで TCP デバイスは待機します。

terminators オプション — TCP バインディング・デバイスで読み取りを終了するユーザ・ターミネータ文字を 8 つまでリストできます。T モードと terminators の両方を同時に指定すると、T モードが無視されます。
ibufsiz

オプション入力バッファ・サイズです。内部的に、ネットワークから読み取られる文字は、Caché プログラムから送信されたものではない場合も、ibufsiz バイトのデータ部にバッファされます。

obufsiz

オプション出力バッファ・サイズです。連続する “SEND” 処理の間に TCP デバイスでバッファできる最大データ量です。SEND 処理は、バッファされたデータをネットワーク外に送信することを意味します。WRITE !WRITE #、および WRITE *-3 の各コマンドは、SEND 処理を生成できます。

S モードを指定した場合、バッファが一杯になると SEND 処理が自動的に生成され、出力バッファの内容が送信されます。それでも、メッセージの生成を完了した後、プログラマは SEND 処理の 1 つを使用し、メッセージが送信されたことを確認する必要があります。

S モードを指定していない場合は、出力バッファ・サイズを超えるデータを WRITE 処理でバッファに置くと、<WRITE> エラーが発生します。出力バッファ・サイズよりも長い文字列を書き込もうとすると、必ず失敗します。

queuesize オプション — サーバ接続を待機する状態に置けるクライアント・ジョブの最大数を指定する整数です。サーバ側の OPEN のみで使用できます。既定値は 5 です。最大値は TCP の実装で異なりますが、どのような場合も 1,000 を超えることはできません。
keepalivetime オプション — (Windows、AIX、Linux のみ) このデバイスに、システムの既定とは異なるキープアライブ・タイマを設定することができます。TCP 接続を保持する秒単位の整数を指定します。有効値は、30 ~ 432000 の範囲 (432,000 秒は 5 日) です。30 未満の値は、既定で 30 となります。省略した場合または 0 に設定した場合は、システムの既定のキープアライブ・タイマが使用されます。

パケット・モード

mode が指定されていない場合、既定でパケット・モードになります。ストリーム・モードが無効の場合、モードは既定でパケット・モードになります。

パケット・モードでは、返すデータが存在する場合はすぐに READ コマンドを完了します。パケット・モードにより、出力バッファに TCP セグメント全体を構築でき、WRITE *-3 あるいは WRITE ! コマンドを発行して、一度にセグメントを送信できます。

送信する文字が存在しないときに、WRITE *-1 を発行し TCP SEND 処理を起動すると、<WRITE> エラーを受け取ります。文字列が空の場合に WRITE を発行すると、<COMMAND> エラーを受け取ります。

パケット・モードで送信できる最大文字列サイズは 1,024 文字です。バッファをフラッシュせずにこの制限サイズを超えると、<WRITE> エラーを受け取ります。

TCP/IP は長さが 0 のレコードを無視するため、文字が存在しない場合に書き込みバッファをフラッシュすると、<WRITE> エラーを受け取ります。

サーバが接続要求を受け取る前に、サーバからクライアントに WRITE コマンドを要求すると、サーバ上で <WRITE> エラーを生成します。

キャリッジ・リターン・モード (C モード)

このモードは、入出力でキャリッジ・リターン処理を変更します。

出力では、WRITE ! は “CR LF” を生成し、WRITE # は “CR FF” を生成します。

入力では、T モードが有効の場合、サーバは隣接する CR と LF、あるいは隣接する CR と FF を、単一のターミネータとして $ZB に記録します。CR と LF が、それぞれ短いインターバルの間に生成されない場合、別のターミネータとして処理されます。既定のインターバルは 1 秒です。

切断の監視モード (D モード)

このモードで、非同期切断の監視をオンまたはオフにします。このモードは、“D” モード文字、/POLL キーワード・パラメータ、または /POLLDISCON キーワード・パラメータを指定することで有効になります。+D を指定すると、TCP 切断の監視がアクティブになり、–D を指定すると TCP 切断の監視が非アクティブになります。

アクティブの間は、Caché によって約 60 秒間隔で TCP 接続がポーリングされます。切断が検出された場合は、<DISCONNECT> エラーが発行されます。切断検出は、HANG コマンドによって中断されたジョブや READ 処理で待機中のジョブなどアイドル・ジョブでは行われません。Caché は、<DISCONNECT> エラーが発生しないように、ロールバック処理中は切断の監視をすべて一時停止します。ロールバックが終了すると、Caché は切断の監視を再開します。この一時停止は、切断の監視が有効な現在の TCP デバイスのほか、切断の監視が無効な現在のデバイスのうち、切断の監視が有効な TCP デバイスに接続しているデバイスにも適用されます。

%SYSTEM.INetInfoOpens in a new tab クラスの Connected()Opens in a new tab メソッドを使用して、TCP 切断をチェックすることもできます。

エスケープ・シーケンス処理モード (E モード)

E モードが設定された場合、入力ストリームのエスケープ・シーケンスは解析され、$ZB 特殊変数に格納されます。エスケープ・シーケンスは、15 文字あるいはそれ以下の必要があり、構文は以下のとおりです。

esc_seq::=type1 | type2

以下はその説明です。

type1 ::= '['['0':'?']*['':'/']*{'@':DEL}  
type2 ::= [';'|'?'|'O']['':'/']*{'0':DEL}

ここで使用されている構文記号の意味は次のとおりです。

: x:y は、ASCII シーケンスで x から y の指定範囲の文字を意味します。
| x|y は、x または y を意味します。
[ ] 0 あるいは指定されたセットのいずれか 1 つのメンバを指定します。
[ ]* 0 あるいは指定されたセットのいずれか 1 つ以上のメンバを指定します。
{ } 指定されたセットのいずれか 1 つのメンバを指定します。

Caché が ESCAPE を検出すると、他のエスケープ・シーケンスが出現するかどうか 1 秒間待機します。エスケープ・シーケンスがこの構文に一致しない場合、長さが 15 文字以上の場合、あるいは有効なエスケープ・シーケンスが 1 秒以内に到着しない場合、Caché は、一部のエスケープ・シーケンスを $ZB に配置し、“BADESC” ビットを $ZA に設定します。

即時送信モード (Q モード)

即時送信モードでは、WRITE コマンドごとにそれぞれのパケットを出力できます。即時送信モードを使用しない場合は、ターミネータを指定するか WRITE *–3 コマンドを発行してパケットを出力する必要があります。

このモードにするには、“Q” モード文字または /SENDIMMEDIATE キーワード・パラメータ (/SEN という表記も可) を指定します。このオプションを無効にするには、次のいずれかを指定します。

   USE TCPDEVICE:(/SEN=0)
   USE TCPDEVICE:(::"-Q")

このオプションを有効にするには、次のいずれかを指定します。

   USE TCPDEVICE:(/SEN=1)
   USE TCPDEVICE:(::"+Q")

書き込みごとに 1 つのパケットを生成する即時送信モードは、各パケットを作成と同時に直ちに送信する /NODELAY モードと組み合わせて使用できます。両方を有効にすると、1 回のデータの転送速度がきわめて速くなります。これは、マウス移動の転送のように、適切な時点で各データ・ユニットを送信する必要がある場合に役立ちます。両方を無効にすると、複数の書き込みを収めたパケットや、複数のパケットの同時転送などが可能になります。その場合は、ネットワーク・トラフィックが減少するので全体的なパフォーマンスが向上します。既定では即時送信モードは無効になっています。/NODELAY モードは既定で有効です。

ストリーム・モード (S モード)

ストリーム・モードでは、Caché は データ・ストリームに TCP メッセージの範囲を保存しようとしません。送信時、データがメッセージ・バッファ・サイズに適合しない場合、Caché は、データをバッファに配置する前に、バッファをフラッシュします。

受信時、最大長までの文字列データを受信できます。すべての読み取りは、ターミネータが完全なタイムアウトに達するまで、あるいはバッファが一杯になるまで待機します。このモードが無効の場合 (既定)、パケット・モードになります。

TCP デバイスを継承するジョブ起動プロセスは、自動的にストリーム形式に設定されます。USE コマンドを使用して、この形式をリセットできます。

バッファ・サイズ

TCP デバイスの ibufsiz パラメータおよび obufsiz パラメータは、TCP 入出力の内部 Caché バッファのサイズを指定します。これにはサポート対象のすべてのプラットフォーム上で、1 KB から 1 MB の範囲内の値を指定できます。ただし、オペレーティング・システムのプラットフォームは、それ自体の入出力バッファに異なるサイズを使用する場合があります。オペレーティング・システム・プラットフォームのバッファが Caché バッファよりも小さい場合 (1 MB に対して 64 KB しかないなど)、パフォーマンスが影響を受ける可能性があります。例えば、WRITE 操作は Caché バッファ全体を送信するために OS に何度も要求を出すことが必要になる可能性があり、READ 操作は OS バッファ・サイズにより制限される複数の小さいチャンクを返す可能性があります。最適なパフォーマンスを得るために、 ibufsiz および obufsiz にどの値を指定すると最適な結果になるかを見極めるには、現在の OS でテストすることが必要です。

サーバ側の OPEN コマンド

サーバ側で OPEN コマンドが処理されると、TCP ソケットが構築され、適切なポート番号に接続要求が入力されるのをソケットで待ち受けます。ポート番号は、パラメータ・リストで明示的に指定します。指定していない場合は、devicename の数値部から取得されます。ソケットが待ち受け状態になるとすぐに、OPEN コマンドが返されます。

OPEN が失敗した場合、別のプロセスがポート番号の接続要求を既に待ち受けている場合があります。

以下の例は、サーバ側の OPEN コマンドを使用して、Caché に類似したデバイスを指定します。これにより、最大文字列サイズ以下の文字列を読み書きできます。また、最大文字列読み取りを使用し、TCP チャネルの使用を統合する処理を書き込みます。

   OPEN "|TCP|4":(:4200:"PSTE"::32767:32767)

この例の parameters 引数は次のようになります。これは、サーバ側の OPEN コマンドなので、最初のパラメータ (hostname) が省略されています。2 番目のパラメータには明示的にポート番号 (4200) を指定します。3 番目のパラメータは、mode コード文字です。4 番目のパラメータ (terminators) は省略されています。5 番目のパラメータは入力バッファのサイズを指定します。6 番目のパラメータは出力バッファのサイズを指定します。

以下の例は、Open M [ISM] バージョン 5.6 以前のバージョンへの下位互換です。ポート番号は、パラメータとして指定されません。devicename の数値部から取得します。この例では、パラメータを指定せず、10 秒のタイムアウトでポート 4200 を開きます。

   OPEN "|TCP|4200"::10

サーバ側の OPEN の入力バッファのサイズ (ibufsiz) と出力バッファのサイズ (obufsiz) の規定のパラメータ値は 1,048,576 バイト (1 Mb) です。

サーバ側の OPEN コマンドは、オプションの queuesize パラメータと、オプションの “G” モード・パラメータをサポートしています。これらのオプションは、クライアント側の OPEN コマンドでは利用できません。

サーバ側の OPEN は、オプションの /CLOSELISTEN キーワード・パラメータをサポートします。このオプションは、クライアント側の OPEN コマンドでは利用できません。

クライアント側の OPEN コマンド

クライアント側の OPEN コマンドがサーバ側の OPEN コマンドと異なる点は、接続するホストを最初のデバイス・パラメータで指定する必要があるということだけです。ホストを指定するには、クライアントでホストあるいはインターネット・アドレスとして認識できる名前を使用します。

OPEN コマンドは、接続されるとすぐに実行します。この時点で、TCP デバイスへの読み取り、あるいは書き込みが可能です。しかし、サーバ側の接続が別の Caché プロセスの場合、WRITE コマンドによるクライアントからサーバへのデータ送信が実行されない限り、サーバ側の接続は完了しません。したがって、READ コマンドの発行前に WRITE コマンドを発行する必要があります。

詳細は、“TCP デバイスの WRITE コマンド” のセクションを参照してください。

以下は、クライアント側の OPEN コマンドの例です。

   OPEN "|TCP|4":("hal":4200::$CHAR(3,4)):10

このコマンドは、ポート 4200 にホスト hal への接続を開きます。モード文字は指定されていません。2 つのターミネータ (ASCII $CHAR(3) および $CHAR(4))、既定の入力バッファ・サイズと出力バッファ・サイズを指定します。さらに、10 秒のタイムアウトを指定します。

以下のコマンドは、宛先の IP アドレスを IPv4 形式で明示的に記述している以外は、上記のコードと同じです。

   OPEN "|TCP|4":("129.200.3.4":4200::$CHAR(3,4)):10

IPv4 および IPv6 の形式に関する詳細は、"Caché プログラミング入門ガイド" の “サーバ構成オプション” の章にある “IPv6 アドレスの使用” のセクションを参照してください。

以下のコマンドは、リモート・ホスト “larry” の時刻サーバに接続し、主要入力デバイスにリモート・ホストの日時を ASCII 形式で出力します。このコマンドではサービス名 daytime を使用しますが、これはローカル・システムでポート番号に解決されます。

   OPEN "|TCP|4":("larry":"daytime":"M")
   USE "|TCP|4" 
   READ x
   USE 0
   WRITE x

以下のコマンドは、x を “hello” に設定します。

   OPEN "|TCP|4":("larry":"echo":"M")
   USE "|TCP|4"
   WRITE "hello",!
   READ x

以下のコマンドは、Open M [ISM] バージョン 5.6 以前のバージョンへの下位互換です。インターネット・アドレス 128.41.0.73、ポート番号 22101 を、30 秒のタイムアウトで接続します。

   OPEN "|TCP|22101":"128.41.0.73":30

TCP デバイスの OPEN コマンド・キーワードと USE コマンド・キーワード

上記で説明した位置パラメータ、またはキーワード・パラメータを使用できます。以下のテーブルは、OPEN コマンドと USE コマンドの両方を使用して、TCP デバイスを制御するキーワードの説明です。OPEN コマンドのみで指定可能な OPEN コマンド専用のキーワード (この章で後述) もあります。キーワード・パラメータはすべてオプションです。

TCP デバイスの OPEN コマンド・キーワードと USE コマンド・キーワード
キーワード 既定 説明
/ABSTIMEOUT[=1] 0 読み取りタイムアウトの動作を指定します。データを受信した際に TCP によってタイムアウト期間を再初期化するかどうかを決定します。/ABSTIMEOUT=0 (既定) の場合は、各時刻データの受信時にタイムアウトを元の値にリセットします。/ABSTIMEOUT もしくは /ABSTIMEOUT=1 の場合は、データを受信する間、タイムアウト期間のカウント・ダウンを続けます。

/ACCEPT[=n]

または

/ACC[=n]

0 “A” モード・パラメータ文字に相当します。クライアント・ジョブからの接続が受け入れられるとすぐに、サーバでの初期の読み取りが長さ 0 の文字列で終了するように指定します。/ACCEPT と /ACCEPT=nn が 0 以外の場合、A モードが有効になります。/ACCEPT=nn が 0 の場合、A モードが無効になります。
/CLOSEFLUSH[=n] 1 デバイスが閉じられている場合、出力バッファに残っているデータの処理を指定します。 /CLOSEFLUSH と /CLOSEFLUSH=nn が 0 以外の場合、残りのデータをフラッシュします。/CLOSEFLUSH=nn が 0 の場合、残りのデータを破棄します。
/CRLF[=n] 0 “C” モード・パラメータ文字に相当します。入出力を戻すキャリッジ・リターン処理を変更します。/CRLF と /CRLF=nn が 0 以外の場合、C モードが有効になります。/CRLF=nn が 0 の場合、C モードが無効になります。

/ESCAPE[=n]

または

/ESC[=n]

0 “E” モード・パラメータ文字に相当します。入力ストリームでエスケープ・シーケンスを構文解析し、$ZB に配置するように指定します。/ESCAPE と /ESCAPE=nn が 0 以外の場合、E モードが有効になります。/ESCAPE=nn が 0 の場合、E モードが無効になります。
/GZIP[=n] 1 GZIP と互換性のあるストリーム・データ圧縮を指定します。/GZIP を指定した場合、または /GZIP=n (n は 0 以外) を指定した場合、WRITE の発行時に圧縮、READ の発行時に解凍が有効になります。/GZIP=0 を指定した場合は、圧縮と解凍が無効になります。/GZIP=0 を発行して、圧縮/解凍を無効にする前に、$ZEOS 特殊変数をチェックして、ストリーム・データの読み込みが実行中でないことを確認してください。/GZIP 圧縮は、/IOTABLE を使用して構築した変換などの入出力変換には影響しません。これは、圧縮がその他すべての変換 (暗号化を除く) の後に適用され、解凍がその他すべての変換 (暗号化を除く) の前に適用されるためです。圧縮データで使用する WRITE に関する詳細は、この章の "WRITE コントロール・コマンド" を参照してください。

/IOTABLE[=name]

または

/IOT[=name]

name が指定されない場合、デバイスの既定の入出力変換テーブルを使用します。 デバイスの入出力変換テーブルを構築します。
/KEEPALIVE=n システムの既定 (Windows、AIX、Linux のみ) このデバイスに、システムの既定とは異なるキープアライブ・タイマを設定することができます。TCP 接続を保持する秒数を指定する整数。keepalivetime 位置パラメータと同じです。有効値は、30 ~ 432000 の範囲 (432,000 秒は 5 日) です。30 未満の値は、既定で 30 となります。省略した場合または 0 に設定した場合は、システムの既定値が使用されます。/NOKEEPALIVE を使用して、この設定を無効にできます。一度無効にすると、TCP デバイスが閉じるまで再度有効にすることはできません。
/NODELAY=n 1 パケットをまとめて送信するか、個々に送信するかを指定します。/NODELAY=1 (既定) に指定すると、パケット単位で直ちに転送されます。/NODELAY=0 に指定すると、最適化アルゴリズムを使用して TCP ドライバでパッケージが 1 つにまとめられます。これにより、パケット単位で見るとわずかな転送遅延が生じる場合がありますが、ネットワーク・トラフィックが減少することで、全体的なパフォーマンスの向上が望めます。/NODELAY に相当するモード・パラメータ文字はありません。/NODELAY は、/SENDIMMEDIATE との関係を考慮して使用する必要があります。
/NOKEEPALIVE   指定した場合、システム規模の TCP キープアライブ・タイマはこのデバイスに対して無効になります。Caché の既定では、TCP デバイスを開く際に、このタイマが有効になります。OPEN または USE で /NOKEEPALIVE オプションを使用すると、この既定をオーバーライドできます。/KEEPALIVE を使用して既定以外のキープアライブ・タイマを設定している場合は、/NOKEEPALIVE によりそのキープアライブ・タイマを無効にできます。一度キープアライブ・タイマを無効にすると、TCP デバイスを閉じるまで再度有効にすることはできません。"/KEEPALIVE" を参照してください。
/NOXY [=n] 0 $X および $Y の処理なし : /NOXY を指定した場合、または /NOXY=n (n は 0 以外の値) を指定した場合、$X および $Y の処理が無効になります。例えば、CSP などで、デバイスの $X/$Y を使用しない場合に、パフォーマンスを向上できます。これにより READ 操作および WRITE 操作のパフォーマンスを大幅に向上させることができます。このオプションは、スーパーサーバ・スレーブ・ジョブの既定の設定です。/NOXY=1 の場合、 $X および $Y の変数値が不確定であるため、マージン処理 ($X に依存) は無効になります。/NOXY=0 の場合は、$X および $Y の処理が有効になります。これが既定です。/TCPNOXY は /NOXY の非推奨の同義語です。
/PAD[=n] 0 “P” モード・パラメータ文字に相当します。これは WRITE ! (LF ターミネータ) または WRITE # (FF ターミネータ) の実行時に、出力にレコード・ターミネータ文字が埋め込まれることを指定します。/PAD と /PAD=nn が 0 以外の場合、P モードが有効になります。/PAD=nn が 0 の場合、P モードが無効になります。

/PARAMS=str

または

/PAR=str

既定なし mode 位置パラメータに相当します (位置に依存しない方法でモード文字列を指定する方法を提供します)。

/POLL[=n]

または

/POLLDISCON[=n]

  切断の非同期監視を指定する “D” モード・パラメータ文字に相当します。/POLL または /POLL=1 は +D に相当し、/POLL=0 は -D に相当します。
/PSTE[=n] 0 “M” モード・パラメータ文字に相当します。これは、P、S、T、E モード・パラメータ文字を指定する省略表現です。/PSTE と /PSTE=nn が 0 以外の場合、P、S、T、E モードが有効になります。/PSTE=nn が 0 の場合、これらのモードが無効になります。

/SENDIMMEDIATE[=n]

または

/SEN[=n]

0 “Q” モード・パラメータ文字に相当します。これは、即時送信モードを指定します。

/SSL="cfg[|pw] [|DNShost]"

or

/TLS="cfg[|pw] [|DNShost]"

既定なし

クライアントが指定した構成とサーバ要件に従い、SSL/TLS で保護された接続のネゴシエーションをデバイスで試行するようにクライアントから指定します。サーバとしてソケットを保護する場合は、サーバが指定した構成とクライアント要件に従い、SSL/TLS で保護された接続をサーバで必要とすることを指定します。

cfg は、接続またはソケットの構成名を指定します。pw は、秘密鍵ファイルのオプションのパスワードを指定します。DNShost は、特定のサーバの完全修飾された DNS ホスト名を指定します。これは、サーバー ネーム インディケーション (SNI) の TLS Extension で使用します。詳細は以下を参照してください

この構成名は、OPEN または USE コマンド後の初回の I/O 動作時にのみ使用されます。それ以降の呼び出しは無視されます。/SSL="" または /TLS="" は無視されます。詳細は、"Caché セキュリティ管理ガイド" の “Caché での SSL/TLS の使用法” の章を参照してください。

重要 : SSL/TLS を使用している新規の TCP 接続を開くときまたはそのような既存の接続を保護するときにパスワードを含める機能は、リアルタイムのインタラクティブを使用する場合にのみ有効です。保護していない秘密鍵パスワードを永続的に保存することは絶対に避けてください。そのようなパスワードを保存する必要がある場合は、Security.SSLConfigsOpens in a new tab クラスの PrivateKeyPassword プロパティを使用します。

/STREAM[=n]

または

/STR[=n]

0 “S” モード・パラメータ文字に相当します。TCP メッセージ範囲を保存しないデータを処理するストリーム・モードを指定します。/STREAM と /STREAM=nn が 0 以外の場合、S モードが有効になります。/STREAM=nn が 0 の場合、S モードが無効になります。
/TCPNOXY   非推奨。/NOXY の同義語です。
/TCPRCVBUF=n 既定の受信バッファ・サイズ。 受信キューのバッファ・サイズをバイト単位で設定します。TCP プロトコルでサイズの大きいウィンドウをサポートするために、バッファ・サイズを既定値から増やす場合に使用できます。ウィンドウのサイズが大きいと、長い遅延を持つリンクまたは広帯域リンクのパフォーマンスが向上します。適切な値については、使用しているオペレーティング・システムやハードウェアのドキュメントを参照してください。
/TCPSNDBUF=n 既定の送信バッファ・サイズ。 送信キューのバッファ・サイズをバイト単位で設定します。TCP プロトコルでサイズの大きいウィンドウをサポートするために、バッファ・サイズを既定値から増やす場合に使用できます。ウィンドウのサイズが大きいと、長い遅延を持つリンクまたは広帯域リンクのパフォーマンスが向上します。適切な値については、使用しているオペレーティング・システムやハードウェアのドキュメントを参照してください。

/TERMINATOR=str

または

/TER=str

既定なし ユーザ定義のターミネータを構築する terminators 位置パラメータに相当します。

/TMODE[=n]

または

/TMO[=n]

0 “T” モード・パラメータ文字に相当します。標準読み取りターミネータで CR、LF、FF を指定します。/TMODE と /TMODE=n の n が 0 以外の場合、T モードが有効になります。/TMODE=nn が 0 の場合、T モードが無効になります。

/TRANSLATE[=n]

または

/TRA[=n]

1 /TRANSLATE を指定した場合、または /TRANSLATE=nn が 0 以外の場合、デバイスの入出力変換が有効になります。/TRANSLATE=nn が 0 の場合はデバイスの入出力変換が無効になります。
/WAIT[=n] 0 “W” モード・パラメータ文字に相当します。出力バッファが、WRITE !WRITE # コマンドでフラッシュされないようにします。フラッシュは次の WRITE *-3 コマンドまで待機します。/WAIT と /WAIT=nn が 0 以外の場合、W モードが有効になります。/WAIT=n の n が 0 の場合、W モードが無効になります。
/WRITETIMEOUT[=n] -1 TCP の書き込み操作のためのタイムアウト (秒) を設定します。書き込みが n 秒以内で完了しない場合、Caché は <TCPWRITE> エラーを発行します。<TCPWRITE> エラーが発行された場合、ユーザ・アプリケーションで即座に TCP デバイスを閉じて、データ損失を防止する必要があります。Caché では、<TCPWRITE> エラーに続けて TCP の書き込み操作を試行することはありません。n の最小値はシステムによって異なります。n がプラットフォームの最小タイムアウト値よりも小さい場合、Caché ではプラットフォームの最小値が使用されます。n を 2 未満とすることはできません。既定 (-1) はタイムアウトの強制がないことを示しています。

/XYTABLE[=name]

または

/XYT[=name]

name が指定されていない場合、デバイスの既定の $X/$Y アクション・テーブルを使用します。 デバイスの $X/$Y アクション・テーブルを構築します。/NOXY を参照してください。

SSL/TLS コンポーネント

TCP デバイスの値は、/SSL または /TLS キーワード・パラメータを引用符付き文字列として開くまたは使用します。この文字列は、1 つ、2 つ、または 3 つのコンポーネントを '|' 文字で区切って持つことができます。

cfg この接続に使用する SSL 構成の名前。このコンポーネントは必須です。
pw オプション — ローカルの秘密鍵ファイルのパスワード。ユーザが昇格されて実行時にパスワードを入力するとき、これはインタラクティブなアプリケーション専用です。これは、永続的に格納されるパスワードでは使用しないでください。永続ストレージには Security.SSLConfigs.PrivateKeyPassword プロパティを使用します。
DNShost

オプション — SSL クライアント専用。サーバ選択証明書 (ホスト名検証用) または特定のサーバの完全修飾 DNS ホスト名 (サーバ名表示用) のいずれかを指定します。 pw を省略した場合、プレースホルダ '|' 文字を指定する必要があります。

ホスト名検証は、クライアントがサーバから受信した証明書に、クライアントが接続しようとしたホスト名のフィールドが含まれていることを、クライアントが確認できるようにする機能です。これは、URL のサーバ名に対応する、完全修飾されたサーバ DNS ホスト名がサーバの X.509 証明書 (subjectAltName Extension または Subject CN フィールド) に含まれていることを確認するクライアント・アプリケーション (%Net.HttpRequest() など) が使用します。これにより、クライアントは、中間者攻撃で間違ったドメインに対して有効な証明書を使用するケースを検出することができます。

サーバ名表示 (SNI) は、クライアントが要求しているホスト名をサーバに送信できるようにする機能です。これにより、複数のドメインを処理するサーバが、複数の証明書のうちの 1 つを選択して返すことができます。サーバは、クライアント上のホスト名の照合に一致するものを選択できます。

以下に示すのは、有効な /TLS キーワード・パラメータの例です。

/TLS="Client"
/TLS="Client|password"
/TLS="Client||www.intersystems.com"
/TLS="Client|password|www.intersystems.com" 

TCP デバイスの OPEN コマンドのみのキーワード

以下の表は、OPEN コマンドのみで指定可能な TCP デバイスを制御するキーワードの説明です。OPEN コマンドまたは USE コマンドで指定可能な OPEN/USE コマンドのキーワード (この章で前述) もあります。キーワード・パラメータはすべてオプションです。

TCP デバイスの OPEN コマンドのみのキーワード
キーワード 既定 説明
/BINDTO[=address]   接続の開始時に使用される指定ローカル・アドレスにバインドします。クライアントの場合は、Caché からの TCP/IP 接続をオープンするときに使用されるソース・アドレスです。サーバの場合は、Caché プロセスが TCP/IP 接続をオープンするときに接続を受け付ける IP アドレスです。/BINDTO=address は、接続で使用されるネットワーク・インタフェースを制御するために使用します。/BINDTO を指定した場合、または /BINDTO=”“ を指定した場合、以前に指定したアドレスは削除されます。
/CLOSELISTEN   (サーバのみ) 待ち受けポートへの複数のリモート接続を防止します。指定すると、最初の接続が受け入れられた後、待ち受けソケットが閉じられます。接続を試みる追加クライアントは、OPEN コマンドでタイムアウトします。

/CONNECTIONS=n

または

/CON=n

5 queuesize 位置パラメータに相当します。サーバへの接続のために待機できるクライアント数を決定します。

/HOSTNAME=str

または

/HOS=str

既定なし hostname 位置パラメータに相当します。IP ホスト名か、IPv4 または IPv6 アドレス形式の IP アドレスを指定します。IPv4 および IPv6 の形式に関する詳細は、"Caché プログラミング入門ガイド" の “サーバ構成オプション” の章にある “IPv6 アドレスの使用” のセクションを参照してください。

/IBUFSIZE=n

または

/IBU[=n]

1024 ibufsiz 位置パラメータに相当します。ネットワークからデータを読み取り、アプリケーションに送信するまで保持する TCP 入力バッファのサイズを指定します。

/OBUFSIZE=n

または

/OBU[=n]

1024 obufsiz 位置パラメータに相当します。連続する "SEND" 処理間でデータを保持する TCP 出力バッファのサイズを指定します。
/PORT=n 既定なし port 位置パラメータに相当します。接続に使用する TCP ポート番号あるいはサービス名です。

/SOCKET=n

または

/SOC=n

既定なし “G” モード・パラメータ文字に相当します。port 位置パラメータが、既に開いているデータ・ソケットのソケット記述子として解釈されます。このキーワードはソケット記述子の値を取得し、/PORT=n キーワードの代わりに使用されます (ソケット記述子は、Caché のコールインまたはコールアウト ($ZF) メカニズムを使用して、他のプログラミング環境 (C など) から ObjectScript に渡されます)。

次は、キーワード構文を使用して TCP/IP デバイスを開く例です。

  SET dev="|TCP|"_123
  SET portnum=57345
  OPEN dev:(/PSTE:/HOSTNAME="128.41.0.73":/PORT=portnum)

現在の TCP デバイス

%SYSTEM.TCPDeviceOpens in a new tab クラスのメソッドを使用して、現在の TCP デバイスの IP アドレスおよびポート番号を返すことができます。以下のように Help() メソッドを使用してこれらのメソッドをリスト表示できます。

  DO $SYSTEM.TCPDevice.Help()

以下の例に示すように、Help() でメソッド名を指定して、特定のメソッドの情報を表示できます。

  DO $SYSTEM.TCPDevice.Help("LocalAddr")

TCP デバイスの USE コマンド

クライアント、サーバのいずれかから発行された USE コマンドにより、事前に開いている TCP 接続を使用して、データの送受信の準備をします。このコマンドの構文は次のとおりです。

USE devicename:(::mode:terminators)

以下はその説明です。

devicename フォーム |TCP| の後ろにいくつかの数字を持つ文字列です。デバイス名の数字部分は、デバイス識別子といいます。OPEN のパラメータでポート番号を指定していない場合、このデバイス識別子には一意な 5 桁の TCP ポート番号を指定する必要があります。OPEN のパラメータでポート番号を指定している場合は (指定することをお勧めします)、1 つのジョブで使用するすべての TCP デバイス名が識別できる限り、このデバイス識別子には任意の一意の番号を指定できます。
mode オプションUSE コマンドは、OPEN と同じパラメータをサポートします。詳細は、“TCP デバイスの OPEN コマンド・キーワードと USE コマンド・キーワード” を参照してください。
terminators オプション — TCP バインディング・デバイスで読み取りを終了するユーザ・ターミネータ文字を 8 つまでリストできます。T モードとユーザ・ターミネータの両方を同時に指定する必要はなく、両方を指定すると、T モードが無視されます。

USE コマンドの最も簡素な形は、次の例に示すように、モード・パラメータとターミネータ・パラメータを OPEN コマンドから受け取るものです。

   USE "|TCP|4"

デバイスを開いた後で、モード・パラメータとユーザ・ターミネータを置き換え、追加、または削除できます。

OPEN コマンドで指定したパラメータを置き換えるには、置き換える値を USE コマンドで指定します。以下の例にある USE コマンドは、OPEN モードを PSTE モードに置き換え、すべてのユーザ・ターミネータをオフにします。

   USE "|TCP|4":(::"PSTE")

OPEN で指定したモード・パラメータを追加または削除するには、“+” 記号を使用して、オンにするモード・パラメータを導き、“-” 記号を使用して、オフにするモード・パラメータを導きます。“+” も “-” も指定しない場合、既存のすべてのモード・パラメータは新規のモード・パラメータ一式に置き換えられます。次の例にある USE コマンドでは、Q モード (直ちに送信) をオンにし、W モード (待機) をオフにします。モード文字列の残り部分は、変更されないままとなります。

   USE "|TCP|4":(::"-Q+W")

以下の例では、USE コマンドはモード文字列を変更せずに、新規のユーザ・ターミネータ一式を指定します。

   USE "|TCP|4":(::"+":$CHAR(3,4))

TCP デバイスの READ コマンド

サーバ、クライアントのいずれかから発行した READ コマンドは、クライアント、サーバのいずれかで設定されたあらゆる文字を読み取ります。

構文は、以下のとおりです。

READ var:timeout
READ *var:timeout
READ var#length:timeout

timeout 引数は、オプションですが、強くお勧めします。これは、timeout が指定されている場合、READ の成功または失敗が、$TEST 特殊変数の値によって示されるためです。$TEST は、時間内に読み取りが成功すると 1 に設定されます。時間が切れると、$TEST は 0 に設定されます。

TCP デバイスでの READ のタイムアウトには、秒を単位として整数または 1 秒未満の小数を指定できます。小数部を持つ 1 以上の値を timeout に指定すると、整数の秒に切り捨てられます (4.9秒 = 4 秒)。1 未満の値を timeout に指定する場合、1/100 秒までの精度で指定できます (0.9 秒 = 9/10 秒)。

SSL 接続では、接続の確立後に他方が読み取りコマンドまたは書き込みコマンドを発行したことがない場合、最初の読み取りコマンドまたは最初の書き込みコマンドでジョブは待機できます。この状況で Caché は、READ コマンドの読み取りタイムアウトおよび WRITE コマンドの書き込みタイムアウト (/WRITETIMEOUT=n オプション) をサポートします。読み取りまたは書き込みのタイムアウトが指定されていない場合、ジョブは他方が読み取りコマンドまたは書き込みコマンドを発行するまで待機します。

%SYSTEM.INetInfoOpens in a new tab クラスの TCPStats()Opens in a new tab メソッドを使用すると、現在の TCP 接続で実行する読み取りの回数を指定できます。

READ による $ZA および $ZB の変更

アプリケーションは、$ZA$ZB の値を検証し、接続と読み取りがどのように成功したかを認識できます。

$ZA と READ コマンド

$ZA は、接続の状態を通知します。設定が 0x1000 ビット (4096) の場合、TCP デバイスはサーバ・モードで機能しています。0x2000 ビット (8192) の場合、リモート・ホストと対話している接続状態です。

例えば、サーバ側の TCP デバイスが、新規 TCP 接続を受け取ると仮定します。Caché プログラムでは、初期のタイムアウト付き読み取り後の $ZA$TEST は、以下の 3 つに分かれます。

$ZA 値 $TEST 値 意味
4096 0 接続は構築されませんでした
12288 0 接続されましたが、データは受信しませんでした
12288 1 接続され、データを受信しました

以下のテーブルは、$ZA の各ビットの意味を示しています。

$ZA の 10 進数値 $ZA の 16 進数値 意味
2 0x2 読み取りがタイムアウトになりました
4 0x4 入出力エラーです
256 0x80 不正なエスケープ・シーケンスを受信しました
4096 0x1000 サーバ・モードです
8192 0x2000 接続されました

$ZB と READ コマンド

$ZB は、読み取りを終了した文字を保持します。文字は以下のうちの 1 つです。

  • キャリッジ・リターンなどの終端文字

  • 固定長 READ x#y の y 番目の文字

  • READ *X の単一文字

  • 読み取りがタイムアウトになったときの空文字列

  • エスケープ・シーケンス

文字列が CR LF で終了した場合、CR のみが $ZB に配置されます。

TCP デバイスの WRITE コマンド

OPENUSE で接続を構築後、WRITE コマンドは、クライアントあるいはサーバから TCP デバイスにデータを送信します。

構文は、以下のとおりです。

WRITE x
WRITE !
WRITE #

WRITE の動作

接続の構築後、WRITE x は、クライアントあるいはサーバからバッファに x を送信します。

WRITE !WRITE # は、改行と改ページを示しません。代わりに、Caché に、バッファに残っている文字をフラッシュし、ネットワークからターゲット・システムへ送信するよう命令します。

%SYSTEM.INetInfoOpens in a new tab クラスの TCPStats()Opens in a new tab メソッドを使用すると、現在の TCP 接続で実行する書き込みの回数を指定できます。

WRITE による $X および $Y の変更

Caché は、$X 特殊変数に、バッファ内の文字数を格納します。

ASCII 文字 <return> と <line feed> はレコードの一部と見なされないため、文字数にカウントされません。WRITE ! でバッファをフラッシュすると、$X を 0 にリセットし、$Y の値を 1 増加します。WRITE # でバッファをフラッシュすると、別のレコードとして ASCII 文字 <form feed> を書き込み、$Y を 0 にリセットします。

WRITE コマンド・エラー

以下のような場合、<WRITE> エラーを受け取ります。

  • バッファをフラッシュせず、最大文字列サイズ (1,024 文字) を超えた場合

  • 文字が存在しない書き込みバッファ (TCP/IP は長さ 0 のレコードを無視します) をフラッシュした場合

  • サーバがクライアントから接続要求を受け取る前に、サーバからクライアントに WRITE コマンドを送信した場合 (Caché は、サーバに <WRITE> エラーを生成します)

WRITE コントロール・コマンド

Caché TCP バインディング・デバイスは、WRITE *-n 構文の一連のコントロール・コマンドをサポートします。

構文 説明
WRITE *-2 現在、クライアントに接続されているサーバ・モード・セッションで、このコマンドはセッションから切断します。新規セッションを受け入れるには、デバイスで新規に READ コマンドを実行します。
WRITE *-3 TCP 接続にバッファされた出力を送信します。つまり、出力バッファのデータに TCP SEND 操作を実行します。/GZIP を指定して圧縮したストリーム・データでは、*-3 を指定すると、圧縮エンドポイントのマークなしでデータが送信されます。$X を 0 にリセットし、$Y を 1 ずつインクリメントします。バッファする出力が存在しない場合、このコマンドは何も実行しません。
WRITE *-99 /GZIP を指定して圧縮されたストリーム・データを送信します。出力バッファにあるデータに圧縮エンドポイントのマークを付けた後、その出力バッファのデータに対して TCP SEND 操作を実行することで圧縮ストリーム・データを送信します。

接続管理

サーバは、一度に 1 つの接続のみ維持できます。したがって、あるクライアントがサーバに接続しているときに 2 番目のクライアントが接続しようとすると、TCP/IP はそのクライアントをキューに格納します。2 番目のクライアントはキューの間、あたかも接続されているかのように、ポートに書き込むことができます。2 番目のクライアントが書き込むデータは、最初の接続が閉じ、2 番目のクライアントに接続するまでバッファに維持されます。

接続が構築される前に READ を発行すると、2 番目のクライアントは停止します。2 番目の接続がキューに入っている間に、3 番目のクライアントが接続を試行しても、その接続は失敗します。

最初の接続がまだ存在しているときに、TCP デバイスを既に開いているクライアントが、2 回目の接続を試行した場合、2 回目の OPEN コマンドでは <COMMAND> エラーが発生します。この状況を USE コマンドではなくエラーとして処理することで、予想できない結果を予防します。例えば、誤ったプログラムが新規に接続を開いたと判断した場合でも、実際には異なる宛先あるいは異なるパラメータを持つ既存の接続を再利用しているたけであると、予測不可能な結果が生じる場合があります。

複数のクライアントを処理する方法は、以下を参照してください。

TCP デバイスを使用した JOB コマンド

JOB コマンドを使用して、TCP 並行サーバ を実装することができます。TCP 並行サーバを使用すると、複数のクライアントを同時に処理できます。このモードでは、クライアントは、サーバが他のクライアント処理を終了するまで待機する必要はありません。代わりに、クライアントがサーバに要求を送信するたびに、開いているクライアントに対して必要に応じて個別のサブジョブを生成します。このサブジョブが生成された直後に (JOB コマンドから制御が戻ります)、他のクライアントが処理を要求することがあります。サーバは、そのクライアントのサブジョブも同様に生成します。

非並行モードおよび並行モードのクライアント/サーバ接続
generated description: ipc connectmodes

並行サーバは、switch 並行サーバ・ビット (ビット 4 またはビット 16) を設定した JOB コマンドを使用します。お勧めの設定はビット 16 です。

  • ビット 4 が設定されている場合、JOB コマンドは、生成したプロセスに、principal input および principal output のプロセス・パラメータの TCP デバイスを渡します。switch にビット 4 が含まれている場合、常に、プロセス・パラメータ principal input および principal output の両方の TCP デバイスを指定する必要があります。また、principal input および principal output の両方に同じデバイスを使用する必要があります。ビット 4 の使用はお勧めしません。詳細は、"Caché ObjectScript リファレンス" の "JOB" コマンドを参照してください。

  • ビット 16 が設定されている場合、JOB コマンドは、生成したプロセスに、TCP デバイス、principal input プロセス・パラメータ、および principal output プロセス・パラメータの 3 つの異なるデバイスを渡します。principal input プロセス・パラメータと principal output プロセス・パラメータを使用して、JOB コマンドでこれらの TCP デバイスのうち 2 つを指定します。以下の例に示すように、これらのパラメータを既定に設定することも可能です。JOB child:(:16:input:output) または JOB child:(:16::))

詳細は、"Caché ObjectScript リファレンス" の "JOB" コマンドを参照してください。

JOB コマンドを実行する前に、principal input および principal output に指定するデバイスは、以下の状態になる必要があります。

  • 接続されている

  • TCP ポートで待ち受け状態にある

  • 接続を受け入れ済みである

JOB コマンドの後、生成されているプロセスのデバイスは継続して TCP ポートで待ち受け状態にありますが、アクティブな接続は既に存在していません。アプリケーションは、JOB コマンドの実行後に $ZA を確認し、TCP デバイスの状態で CONNECTED ビットがリセットされていることを確認する必要があります。

生成されたプロセスは、指定の TCP デバイスを使用して指定のエントリ・ポイントで開始します。子プロセスの TCP デバイス名は、親プロセスの名前と同じです。TCP デバイスには、付属のソケットが 1 つあります。継承された TCP デバイスは、S (ストリーム) モードです。しかし、子プロセスは、USE コマンドでモードを変更できます。サーバは、TCP デバイスを A (受信) モードで開くことをお勧めします。

生成したプロセスにある TCP デバイスは、接続状態です。これは、デバイスをクライアントから開いた後に受け取る状態と同じです。生成されたプロセスは、TCP デバイスを USE 0 あるいは USE $P で使用します。また、TCP デバイスを暗黙的に使用することもできます (switch=4 の場合)。ただし、以下の理由により switch=16 が switch=4 よりも優先されます。

  • switch=4 の場合、<READ> エラーが主デバイス上で発生すると、エラー・トラップをせず、ジョブは単に停止します。これは、switch=4 の場合、TCP デバイスが主デバイスであるためです。エラー・トラップをサポートするには、switch=16 を使用し、TCP デバイスに別のデバイスを指定します。

  • switch=4 の場合、リモート TCP デバイスが接続を終了すると、エラー・トラップをせず、ジョブは単に停止します。この既定の動作をオーバーライドし、<DSCON> エラーを生成するには、%SYSTEM.ProcessOpens in a new tab クラスの DisconnectErr()Opens in a new tab メソッドを設定する必要があります。

JOB コマンドではなく %SYSTEM.SocketOpens in a new tab クラス・メソッドを使用して並行 TCP サーバ接続を作成できます。ただし、%SYSTEM.SocketOpens in a new tab メソッドはスレーブ・ジョブが既に開始されていることを想定していることに注意してください。スレーブ・ジョブを開始するためにマスタ・サーバが不要な場合、並行 TCP サーバ接続にこれらのメソッドを使用できます。マスタ・サーバはスレーブ・ジョブのプロセス ID (PID) を認識しています。

Job コマンドの例

以下の例は、非常に単純な並行サーバです。このサーバは、クライアントからの接続を検出するたびに子ジョブを生成します。JOB により並行サーバ・ビットの switch の値 (値 16) を指定して、シンボル・テーブル (値 1) を渡します :16+1=17。

server
  SET io="|TCP|1" 
  SET ^serverport=7001 
  OPEN io:(:^serverport:"MA"):200 
  IF ('$TEST) { 
       WRITE !,"Cannot open server port" 
       QUIT }
  ELSE { WRITE !,"Server port opened" }
loop
     USE io READ x ; Read for accept 
     USE 0 WRITE !,"Accepted connection" 
     JOB child:(:17:io:io) ;Concurrent server bit is on 
     GOTO loop
child
  WRITE $JOB,! ; Send job id on TCP device to be read by client 
  QUIT
client
  SET io="|TCP|2" 
  SET host="127.0.0.1" 
  OPEN io:(host:^serverport:"M"):200 ;Connect to server
   IF ('$TEST) { 
       WRITE !,"cannot open connection" Quit }
   ELSE { 
       WRITE !,"Client connection opened" 
       USE io READ x#3:200 ;Reads from subjob 
       }
   IF ('$TEST) { 
       WRITE !,"No message from child" 
       CLOSE io 
       QUIT }
   ELSE {
       USE 0 WRITE !,"Child is on job ",x 
       CLOSE io 
       QUIT }

子ジョブは、継承した TCP 接続を使用して、ジョブ ID (この場合は 3 文字とします) をクライアントに渡します。その後、子プロセスは終了します。クライアントは、サーバとの接続を開き、その状態で子のジョブ ID を読み取ります。この例では、変数 host に IPv4 形式で指定した値 “127.0.0.1” により、ローカル・ホスト・マシンへのループバック接続であることを示しています。host にサーバの IP アドレスまたは名前を設定すれば、そのサーバとは別のマシンにクライアントをセットアップすることもできます。IPv4 および IPv6 の形式に関する詳細は、"Caché プログラミング入門ガイド" の “サーバ構成オプション” の章にある “IPv6 アドレスの使用” のセクションを参照してください。

原則では、子プロセスとクライアントは広範囲の通信を実行できます。複数のクライアントが同時に対応するサーバの子と通信できます。

この単純な例には、切断または失敗した読み取り処理を検出し、処理するロジックは含まれていません。

レコードの連結

特定の環境で、TCP は、別々のレコードを 1 つのレコードに連結します。クライアントあるいはサーバ・プロセスが、バッファをフラッシュするために WRITE ! あるいは WRITE # コマンドで区切られた一連の WRITE コマンドを TCP ポートに発行した場合、READ コマンドが他の接続の切断を待機しているかどうかにかかわらず、レコードの連結が可能です。

最初の例は、Process B が TCP ポートに 2 つのレコードを書き込む間、READ コマンドを持つ Process A がどのように 2 つのレコードを受信するのかを説明しています。

Process A                            Process B
%SYS> USE "|TCP|41880" R A U 0 W A   %SYS> USE "|TCP|41880" WRITE "ONE",!,"TWO"
<RETURN>                             <RETURN>
ONE
%SYS> USE 41880 R A U 0 W A 
<RETURN>
TWO

2 番目の例は、Process B が TCP ポートに 2 つのレコードを記述し、その後、READ コマンドを発行した Process A がどのように 1 つの連結レコードを受信するのかを説明しています。

Process A                           Process B
.                                   %SYS> USE "|TCP|41880" WRITE "ONE",!,"TWO"
.                                   <RETURN>
ONE
%SYS> USE "/TCP/41880" R A U 0 W A 
<RETURN>
ONETWO

Caché TCP デバイスの多重化

%SYSTEM.SocketOpens in a new tab クラスは Caché TCP デバイスの多重化のためのメソッドを提供します。Fork() および Select() メソッドにより、新規接続の受け入れ、および接続した TCP デバイスからのデータ読み取りを両方同時に処理する単一ジョブが可能になります。待ち受け TCP デバイスが接続を受け入れた後に、Fork()Opens in a new tab を使用して、データ読み取りのための新規 TCP デバイスを作成します。元の待ち受け TCP デバイスは着信接続の受け入れを続行します。Select()Opens in a new tab メソッドを使用して、待ち受けおよび接続した TCP デバイスの両方に対して待機を行います。新規接続が着信するか、またはデータが使用可能になった場合、Select() は信号を受けたデバイス名を返します。

Select()Opens in a new tabPublish()Opens in a new tabExport()Opens in a new tab、および Import()Opens in a new tab メソッドを使用すれば、マスタ・ジョブの着信接続受入れとスレーブ・ジョブへの接続デバイス受け渡しが可能になります。このスレーブ・ジョブはリモート・クライアントとの通信が可能となっています。

詳細およびプログラム例については、"インターシステムズ・クラス・リファレンス" の %SYSTEM.SocketOpens in a new tab クラスを参照してください。

接続の切断

クライアントあるいはサーバのいずれでも、TCP バインディング接続を切断できます。接続を閉じるには、クライアントが TCP デバイスに対して CLOSE コマンドを発行することをお勧めします(または、クライアントが HALT コマンドを発行します)。サーバは、その後、そのデバイスに別の READ コマンドを発行して <READ> エラーを受け取り、さらに TCP デバイスに対して CLOSE コマンドを発行する必要があります。

この順序にするのは、TCP/IP 標準に従って、CLOSE の後 2 分間、“アクティブなクローザ“ (CLOSE を最初に実行するプロセス) に対してのみ、接続リソースを維持するためです。したがって、サーバのリソースは通常クライアントのリソースよりも制約が多いため、クライアントを最初に閉じることをお勧めします。

CLOSE コマンドによる切断

以下の形式で、クライアントあるいはサーバから CLOSE コマンドを発行します。

CLOSE "|TCP|devicenum"

上述のように、クライアントが最初に CLOSE コマンドを発行することをお勧めします。サーバが CLOSE コマンドを発行する場合、クライアントは <WRITE> エラーを取得するので、CLOSE コマンドを発行する必要があります。

JOBSERVER リソース

管理下にないクライアントにアクセスするよう Caché サーバを記述している場合、サーバ・プロセスは、CLOSE を発行して TCP 接続を閉じる必要があります。CLOSE コマンドは、Caché に関しては接続を閉じますが、内部的に TCP/IP は、最大 2 分間サーバ上でこの接続のためのリソースを保持します。

これによって、TCP/IP ジョブへのサービスの提供のために JOBSERVER が使用される場合、予期しない結果が生じる可能性があります。JOBSERVER プロセスが停止を実行すると、プロセスは、直ちに使用可能な JOBSERVER プロセスのプールに戻りますが、そのリソースは、最大 2 分間内部的に保持されます。JOBSERVER プロセスは、最初に使用可能なものから割り当てられるので、比較的少数のクライアントからの重い負荷が JOBSERVER プロセスのリソースを使い果たす可能性があります。

この問題を回避するために、JOBSERVER の下で実行されている JOB によって開かれた TCP/IP サーバは、明示的に CLOSE を発行し、その後、最後の QUIT (または HALT) コマンドの前に短い HANG コマンドを発行する必要があります。TCP/IP の仕様に従って、JOBSERVER における各状態の間でリソースが使用中のままにならないことを保証するには HANG 120 が必要です。実際には、通常、JOBSERVER プロセス間でリソースの負荷を均等に分散するには、1 秒の HANG で十分です。

サーバでの WRITE *-2 コマンドによる切断

サーバが、あるクライアントを切断する必要がある場合は、WRITE *-2 コマンドを使用します。これにより、別のクライアントの接続を受け入れることができます。

   WRITE *-2

このオプションは、旧バージョンとの互換性を考慮して、“DISCONNECT” 付き USE コマンドは今後のバージョンでは廃止される予定です。

新規セッションを受け入れるには、そのデバイスに対して新規に READ コマンドを実行します。

切断されたクライアントは、TCP デバイスに CLOSE コマンドを発行し、デバイスを解放する必要があります。

自動切断

以下の条件の場合、TCP バインディング接続は自動的に切断します。

  • Caché の致命的なエラー

  • クライアント・プロセスあるいはサーバ・プロセスの RESJOB

  • ccontrol コマンドによる停止

  • ccontrol コマンドによる強制終了

切断の影響

出力バッファに残っているデータへの切断の影響は、OPEN または USE 中に確立される /CLOSEFLUSH 設定によって決まります。既定では、データをフラッシュします。

片方で接続を切断し、もう一方で新規に WRITE コマンドを発行すると、最初の WRITE コマンドは成功する場合があります。続けて WRITE コマンドを発行すると、<WRITE> エラーを受け取ります。

クライアント側から、接続を切断した側へ READ コマンドを発行すると、<READ> エラーを受け取ります。サーバで通信を再構築するため、デバイスを一度閉じてから再度開く必要があります。

<READ> エラーまたは <WRITE> エラーの後で、サーバ側から発行した最初の READ コマンドは、新規接続を待機して受け入れます。

%SYSTEM.TCPDevice.GetDisconnectCode()Opens in a new tab を使用すれば、現在の TCP デバイスで <READ> または <WRITE> エラーとなった内部エラーを返すことができます。$IO は TCP デバイスとする必要があります。

FeedbackOpens in a new tab