ユーザがトランスポートエンドポイントにアドレスをバインドさせた後、データグラムはエンドポイントを介し送受信が可能になります。各送信メッセージは宛先ユーザーのアドレスとともに送信されます。また 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) が呼び出され、応答はクライアントに送信されます。