ユーザがトランスポートエンドポイントにアドレスをバインドさせた後、データグラムはエンドポイントを介し送受信が可能になります。各送信メッセージは宛先ユーザーのアドレスとともに送信されます。また XTI/TLI はデータユニット転送へのプロトコルオプションの指定を可能にします (たとえば、transit delay )。各トランスポートプロバイダはオプションセットをデータグラム上で定義します。データグラムが宛先ユーザーに渡された時点で、関連付けられたプロトコルオプションも渡されます。
例 3-2 は、コネクションレスモードサーバーのデータ転送フェーズの例です。
if ((ud = (struct t_unitdata *) t_alloc(fd, T_UNITDATA,T_ALL))
== (struct t_unitdata *) NULL) {
t_error("t_alloc of t_unitdata struct failed");
exit(5);
}
if ((uderr = (struct t_uderr *) t_alloc(fd, T_UDERROR, T_ALL))
== (struct t_uderr *) NULL) {
t_error("t_alloc of t_uderr struct failed");
exit(6);
}
while(1) {
if (t_rcvudata(fd, ud, &flags) == -1) {
if (t_errno == TLOOK) {
/* 前に送られたデータグラムのエラ−*/
if(t_rcvuderr(fd, uderr) == -1) {
exit(7);
}
fprintf(stderr, "bad datagram, error=%d¥n",
uderr->error);
continue;
}
t_error("t_rcvudata failed");
exit(8);
}
/*
* Query() が要求の処理を行い、応答を ud->udata.buf に格納、
* ud->udata.len が設定される。
*/
query(ud);
if (t_sndudata(fd, ud) == -1) {
t_error("t_sndudata failed");
exit(9);
}
}
}
/* 引数の使用 */
void
query(ud)
struct t_unitdate *ud;
{
/* 簡略化のため関数の切り口のみ */
}
データグラムのバッファー化を行うにはサーバーはまず以下の形式を持つ t_unitdata 構造体の割り当てを行う必要があります。
struct t_unitdata {
struct netbuf addr;
struct netbuf opt;
struct netbuf udata;
}
addr は入力されるデータグラムの送信元アドレスと、出力されるデータグラムの宛先アドレスを保持します。opt はデータグラムのプロトコルオプションを保持します (プロトコルオプションがある場合)。udata はデータを保持します。addr、opt、および udata フィールドはいかなる入力値にも対応できるよう、十分なバッファーを割り当てておく必要があります。 これを確実に行うため、t_alloc(3NSL) の T_ALL 引数は各 netbuf 構造体の maxlen フィールドを必要に応じ設定します。この例ではプロバイダはプロトコルオプションをサポートしていないため、opt の netbuf 構造体の maxlen は 0 に設定されています。またサーバーはデータグラムエラー用に t_uderr 構造体の割り当てを行います。
トランザクションサーバーは無限ループ状態でクエリーの受信、処理およびクライアントへの応答を行います。最初に次のクエリーを受信するため t_rcvudata(3NSL) を呼び出します。t_rcvudata(3NSL) はデータグラムが入力されるまでブロックし、クエリーを戻します。
t_rcvudata(3NSL) の 2 番目の引数はデータグラムのバッファーを行うための t_unitdata 構造体を特定しています。
3 番目の引数 flags は整数型変数を指し、t_rcvudata(3NSL) からの戻り値にユーザーの udata バッファーがデータグラムを格納するだけの大きさが確保されていないことを示す T_MORE が設定されることが可能です。
上の事態が発生した場合、t_rcvudata(3NSL) の次の呼び出しは残りのデータグラムを取り戻します。t_alloc(3NSL) が最大サイズのデータグラムを格納するのに十分な大きさの udata バッファーを割り当てるため、このトランザクションサーバーは flags のチェックを行う必要がありません。これは t_rcvudata(3NSL) のみに当てはまり、他の受信プリミティブには適用されません。
データグラムが受信された場合、トランザクションサーバーは要求の処理を行うため、query ルーチンを呼び出します。このルーチンは ud が指す構造体に応答を格納し、ud->udata.len を応答のバイト数に合わせ設定します。t_rcvudata(3NSL) により戻される ud->addr の送信元アドレスは t_sndudata(3NSL) の宛先アドレスです。応答の準備が完了した時点で、t_sndudata(3NSL) が呼び出され、応答はクライアントに送信されます。