2009-06-12 7 views
3

私はオプションのサーバーアプリケーションに通知メッセージを送信するクライアントアプリケーションを用意しています。クライアントは、サーバーアプリケーションが存在するかどうかによって影響を受けるべきではありません。サーバーアプリケーションに接続して通知メッセージを送信しようとする必要があります。エラーが発生した場合は、すべてのエラーを無視して作業を続行します。Indyの強力な単方向メッセージ

私はTCP通信にIndyを使用していますが、エラーメッセージが表示されないようにする(つまり、サーバーアプリケーションがクライアントに接続しているときに閉じる)ことはできませんでした。

これを本当に堅牢にする方法はありますか?

現在のコードは次のようになります。

if (not Client.Connected) then 
    begin 
    Client.Host := ServerName; 
    Client.Port := ServerPort; 
    Client.ConnectTimeout := ConnectTimeout; 
    try 
    Client.Connect; 
    except 
    Exit; 
    end; 
    end 
try 
    Client.IOHandler.WriteLn ('NOTIFYCHANGE "' + Param + '"'); 
    Client.IOHandler.WriteBufferFlush; 
except 
    try 
    Client.Disconnect; 
    except 
    { ignore errors while disconnecting } 
    end; 
    try 
    Client.Connect; 
    except 
    { ignore errors while connecting } 
    end; 
end; 

答えて

3

は、あなたが本当にあなたのプログラムからのエラーメッセージを得るのですか?デバッガが例外を検出してプログラムを中断するデバッグを行うと、デバッガのメッセージに自分のプログラムからのメッセージが混乱することがよくあります。あなたはそれがここのケースではないと確信していますか?

  • 使用「の高度なブレークポイント」のコードの領域についてのデバッガの例外傍受の動作を無効にする:I've written about this situation before.はここでそれを回避するための方法の概要です。
  • 例外の特定のクラスを無視するようにデバッガを構成します。 (これは多くの例外をスローする傾向があるため、Indyと特に共通しています)
  • デバッガが例外時にプログラムを中断しないように設定します。
  • 統合デバッグを完全に無効にします。メッセージが本当にデバッガプログラムから来ていない場合は

、その後、戻って、メッセージがどこから来ている把握する使用デバッガ。メッセージが表示されたら、プログラムを一時停止し、コールスタックウィンドウを参照して、メッセージを表示しているコードの領域を見つけます。これは、表示されたコードに明確に含まれていないためです。表示されたコードは、Indyに関連しないものであっても、すべての例外(例えば、EAccessViolationおよびEOutOfMemoryなど)を徹底的に抑制しています。

+0

こんにちは、ロブ、答えてくれてありがとう。デバッガでアプリケーションを実行していないときにメッセージが表示されます。私はすべての通知に接続したり切断したりすることで修正しました(頻繁に起こることはありません)。今はかなり頑丈なようです。 – jpfollenius

0

可能であれば、UDPの使用を検討してください。それは "コネクションレス"なので、送信者は単にメッセージを送信し、受信アプリケーションはポートを聴いている場合にそれを受信します。ただし、サーバーが何らかの確認を送信しない限り、送信者は配信に関する確認を取得しません。

+0

私はexistinc通信プロトコルを使いたいので、TCPを使いたいと思っています。とにかくありがとう。 – jpfollenius

+0

インディーズは永遠にUDPを持っていました。あるいは、アプリケーションがすでにやっていることに合わせたいと思っていた「既存の通信プロトコル」という意味ですか? –

0

Harrivの応答はOKです。UDP接続の動作について説明しています。私も同様の状況で使用しています。

2

私はSynapseパッケージを使用した単純なTCP通信タスクのために、Indyと同じくらい膨らんでいないし、 "クリーナー"と感じています。私の最近のコードから

procedure SendMessage(m: string); 
var 
    sock : TTCPBlockSocket; 
    response : string; 
begin 
    Sock := TTCPBlockSocket.Create; 
    try 
    Sock.SetTimeout(200); 
    Sock.Connect(PrinterServerAddr, IntToStr(PrinterServerPort)); 

    Sock.SendString(m); 
    response := Sock.RecvString(1000); 
    finally 
    Sock.Free; 
    end; 
end; 

.. 
try 
    SendMessage(NewMessage); 
except 
//..handle exception.. 
end; 

ラップのTThreadの内側に、あなたの現在のスレッドをブロックしないようにしたい場合。

0

あなたはIndy 9か10を使用しているかどうかは言いません。私は9を使用していますので、これを前提としています。

なぜこれだけではありませんか?:

procedure Send(Target: String; Port: Integer; S: String); 
var 
    C: TIdTcpClient; 
begin 
    C := TIdTcpClient.Create(nil); 
    try 
    try 
     C.Host := Target; 
     C.Port := Port; 
     C.Connect; 
     try 
     C.Write(S); 
     finally 
     C.Disconnect; 
     end; 
    except 
     // Ignore Indy exceptions 
     on EIdException do; 
    end; 
    finally 
    C.Free; 
    end; 
end; 

これを既存のTIdTcpClientを使用する手順に変えるのは簡単です。

関連する問題