Japan QualNet Community Forums Japan QualNet Community Forums
Welcome Guest 
ログイン
ユーザ名:

パスワード:


パスワード紛失

新規登録
検索
メインメニュー
アクセスカウンター
2024/05/17:12/13
2024/05/16:22/24

2024/03/18より397/1407
人気モジュール
No.1: フォーラム 96
No.2: QualNet概要 3
No.3: ニュース 2
日曜日からの合計
人気Browser&OS
No.1:巡回ロボット78
No.2:Unknown OS1
No.3:Windows XP1

No.1:どっかの巡回ロボット69
No.2:Majestic-12巡回ロボット6
No.3:Google巡回ロボット3

日曜日からの合計
メイン
   Application Layer Protocol Implementation & Model Development
     タイマー、スケジュール、トリガーについて。
投稿するにはまず登録を

スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 スレッド
masa
投稿日時: 2006/11/18 15:51
新米
登録日: 2006/8/12
居住地:
投稿: 14
タイマー、スケジュール、トリガーについて。
いつもお世話になっております。
現在MCBRをいくらか改良し、次のような状況を実現しようとしています。

? MCBRを利用して、クライアントはネットワーク全体にフラッディングを行う。
? フラッディングパケットを受け取ったサーバはクライアントに対してユニキャストで返答する。
? クライアントは一定時間待機し、その間に受け取ったサーバからのメッセージを解析して一番条件に適したものに対してのみユニキャストで応答する。
? クライアントからの応答を受け取ったサーバは再度クライアントに対してユニキャストで応答する。


ここで、?においてタイマーを1秒間に設定してその時刻になったときにメッセージを送り、それをトリガーとしてサーバに対してユニキャストメッセージを送るようプログラムを作ろうとしましたがユニキャストの送信が実行されません。

一般論でも全く構いませんので、このようなスケジューリングの下でパケット送信を成功させるためにはどのようなことを行えばよいのかをご教授いただけませんでしょうか。よろしくお願いします。


参考までに、私が行っている方法を記述します。
タイマーメッセージを生成する時には

  Message* timerMsg = NULL;
      clocktype ACKstartTime;
      AppTimer *timer;

      timerMsg = MESSAGE_Alloc(node, APP_LAYER, APP_MCBR_CLIENT, MSG_APP_MCBR_AREP_PKT);
      MESSAGE_InfoAlloc(node, timerMsg, sizeof(AppTimer));
      timer = (AppTimer *)MESSAGE_ReturnInfo(timerMsg);
      timer->sourcePort = (short) clientPtr->sourcePort;
      timer->type = APP_TIMER_SEND_PKT;//自作タイプ → API.cppに追加
      ACKstartTime = 1 * SECOND;
      MESSAGE_Send(node, timerMsg, ACKstartTime);

タイマーをトリガーとして認識する部分は
  case MSG_APP_MCBR_AREP_PKT:
   {
        ・
        ・
        ・
  switch (timer->type)
          
            case APP_TIMER_SEND_PKT:
          {       
                 ・
                 ・
                 ・ 


ユニキャストを送るときの関数としては

APP_UdpSendNewHeaderVirtualDataWithPriority

を利用しています。
パケットを受信したことをトリガーとする場合、

LookupData data_lookup;
memcpy(&data_lookup, MESSAGE_ReturnPacket(msg), sizeof(data_lookup));
clientPtr = AppMCbrClientGetMCbrClient(
node,
data.sourcePort);

という処理を行い、この data_lookup 、 clientPtr を APP_UdpSendNewHeaderVirtualDataWithPriority に変数として代入すればうまくユニキャストが発生するのですが、今回のようにタイマーをトリガーとする場合は、パケットが発生しないので MESSAGE_ReturnPacket の利用が出来ず、これらの値を使えないのがユニキャスト不発の原因なのではないかと考えいます。

masa
投稿日時: 2006/11/20 8:06
新米
登録日: 2006/8/12
居住地:
投稿: 14
Re: タイマー、スケジュール、トリガーについて。
長々とした文で要旨が判りづらくて申し訳ありません。
質問内容を短くまとめます。

スケジュールを使う際、send_message で送るのはスケジュール情報だけになると思います。そのため、

memcpy(&data, MESSAGE_ReturnPacket(msg), sizeof(data));

といったような処理ができないと思います。そうなると、

APP_UdpSendNewHeaderVirtualDataWithPriority

のような関数に渡す引数を確保する事ができません。
やはりLookupでも行われているように最初にdataを定義し、そのdataに値を入力していき、そのdata構造を関数の引数とする、という方法が一般的なのでしょうか。
gaku
投稿日時: 2006/11/20 10:03
半人前
登録日: 2005/12/14
居住地:
投稿: 31
Re: タイマー、スケジュール、トリガーについて。
# こういう処理はやったことがないので、あまりアテになるお答え
はできませんが・・・。
スケジューラを使用した場合に、受け取ったMessageから直接データを作成する処理は確かに現状の実装では見ないですね。

逆に、Lookupで行われているようなやり方を引き継ぐ場合にはどの辺りに問題点があるのでしょうか。
あまり状況が見えてなくて申し訳ないですが。
サーバから受信したデータの解析結果を送信データに反映させないといけないということですか。
gaku
投稿日時: 2006/11/20 10:28
半人前
登録日: 2005/12/14
居住地:
投稿: 31
Re: タイマー、スケジュール、トリガーについて。
連続投稿で失礼します。
自分がやったことはないし、もう試行されているかもしれませんがスケジュールを使う際、send_message に含むMessageの中にデータを詰められないでしょうか。(スケジュール情報以外のものを格納する)
最初の投稿でのソースを見るとMESSAGE_PacketAllocがないので、元々データを格納する処理を行っていないように見えます。
# 繰り返しますが、実際にやったことはないのでうまくいかないかもしれません。
kabocha
投稿日時: 2006/11/20 10:36
常連
登録日: 2006/9/8
居住地:
投稿: 43
Re: タイマー、スケジュール、トリガーについて。
引用:

masaさんは書きました:
スケジュールを使う際、send_message で送るのはスケジュール情報だけになると思います。そのため、



ここで、すでに誤解されているような気がします。

Message_Send でシミュレーションエンジンに対して送るのは確かにスケジュール情報ですが、これにタイマーイベントとパケットイベント(パケットそのもの)の2種類があります。で、いずれもMessageデータ構造を
送ることで実現します。

Message_ReturnPacket を使うのはパケットイベントを受け取った際に、パケットの中身をMessageデータ構造から受け取る場合です。つまりだれかが作ったパケットを参照したい場合に使います。

当然、自分でパケットを送る際にはMessageデータ構造に対して、Packetデータを設定してあげる必要があります。最初にパケットを作る人は当然データを作成しなければなりません。

APP_UdpSendNewHeaderVirtualDataWithPriority

はデータを引数で受け取ったあと、

Message* APP_UdpCreateNewHeaderVirtualDataWithPriority(..省略)

というAPIを呼び出しています。これで、UDPヘッダーがついたパケットをもつMessageデータ構造が出来上がるわけです。

通常、自分でタイマーを仕掛けてパケットを生成したいなら、パケットハンドラの処理で、以下のようにするのが通常の手順だと思います。


     switch (msg->eventType)
     {
         case MSG_APP_TimerExpired:
         {
             AppTimer *timer;
 
            timer = (AppTimer *) MESSAGE_ReturnInfo(msg);
 
             switch (timer->type)
             {
                 case APP_TIMER_SEND_PKT:
                  
        ここで新しいパケットのデータを作成
        APP_UdpSendNewHeaderVirtualDataWithPriority
                を呼び出すと、中でパケットメッセージを勝手に
        作ってくれる


このあたりのことは、ver3.9.5 のプログラマーズガイド 3.3 章あたりを熟読すれば理解できると思いますがいかがですか?
masa
投稿日時: 2006/11/20 20:02
新米
登録日: 2006/8/12
居住地:
投稿: 14
Re: タイマー、スケジュール、トリガーについて。
gaku さん、kabocha さん、早速ご返答ありがとうございます。


「逆に、Lookupで行われているようなやり方を引き継ぐ場合にはどの辺りに問題点があるのでしょうか。」
ということですが、本当はそのまま LOOKUP クライアントの動作を引き継ぐに越したことないです。ただ、どうも自分自身のスキルの問題か、この方法で実装するとエラーが止まらず、仕方なく LOOKUP サーバでの手法を取るに至ったしだいです。本当に面目ないです・・・。

kabocha さんからのご指摘についてですが、Message_Send がタイマーイベントとパケットイベントで使われているのは一応把握しているつもりです。ただ、1秒後にイベントを発生させる、という処理を行う時には msg が持つのはタイマーイベントの情報だけであり、そこにパケットの情報はなく、その後パケット送信などを行う際には

APP_UdpSendNewHeaderVirtualDataWithPriority

などの関数で Message_Send を使いパケットイベントとして msg がパケットの情報をもつようになるものと認識しています。

やはりこのような状況では、お二人にご指摘を受けたように一度パケットデータの設定をしなおさなければならないということですね!
パケットデータを設定についてですが、lookup.cpp で言えば


LookupData data;
・・・
data.type = 'c';
・・・
data.sourcePort = clientPtr->sourcePort;
data.txTime = getSimTime(node);
・・・
data.tos = clientPtr->tos;


辺りのことを仰っているのだと思うのですが、間違いありませんでしょうか。最初の Message_Send でタイマーイベントの開始、その後はパケットのデータの設定、

APP_UdpSendNewHeaderVirtualDataWithPriority

を利用してのパケット生成という流れでもう一度プログラミングを行ってみようと思います!
ありがとうございました ^^

スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ
Copyright c KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved.
XOOPS Cube PROJECT