- - PR -
Socket.Exceptionでハンドルされていない例外
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2004-01-11 08:02
諸農です。
私の言葉がきつすぎたかもしれません。。 すみませんでした。 ただ、出直して来いというつもりはなく、 FCL1.0からFCL1.1へのコンバージョンで動かせるように なるための情報交換は、継続してここのフォーラムで やっていってもいいと思っています。 それは今後のプログラミングに向けての勉強になるのだと 思いますし、もう一つは、せっかく購入した書籍の、一つ の活用方法だと思いますから。 #著者の名誉回復にもつながるのでは? ではでは(^^)/ _________________ 諸農和岳 Powered by Turbo Delphi & Microsoft Visual Studio 2005 十兵衛@わんくま同盟 http://blogs.wankuma.com/jubei/ | ||||||||||||
|
投稿日時: 2004-01-12 09:39
割り込み失礼します。私も御気楽堂さんとまったく同じ問題で悩んでおり、こちらのツリーを興味深く拝見しておりました。
当方はローカルネットワーク環境用のプログラムを作成しており、サーバのIPアドレスは固定なのですが、サーバを立ち上げていない状態でクライアントのプログラムを起動すると、御気楽堂さんの現象と同じく以下のように言われて、プログラムの実行が中断してしまいます。 「'System.Net.Sockets.SocketException' のハンドルされていない例外がsystem.dll で発生しました。追加情報 : 接続済みの呼び出し先が一定の時間を過ぎても正しく応答しなかったため、接続できませんでした。または接続済みのホストが応答しなかったため、確立された接続は失敗しました。」 コードはこんな感じです。 プログラムをわかりやすくするためIPアドレスとポート番号は固定にしてあります。 // Get the stream string serverIPaddress = "192.168.0.32"; string serverPortNo = "32000"; IPAddress server; NetworkStream s; try { server = IPAddress.Parse(serverIPaddress); tcpc.Connect(server, serverPortNo); s = tcpc.GetStream(); } catch (ObjectDisposedException e) { Trace.WriteLine(e.ToString()); //実際にはこうではないです //再試行へ } catch (InvalidOperationException e) { Trace.WriteLine(e.ToString()); //再試行へ } catch (Exception e) { Trace.WriteLine(e.ToString()); //再試行へ } プログラムが「GetStream」で中断するため、再試行に移行してくれません。 デバッグウィンドウには「プログラム '[848] XXXXX.exe' はコード 0 (0x0) で終了しました。」と表示されます。 サーバが立ち上がっていれば問題なく動作します。 「GetStream」を呼び出してから数秒でエラーが発生するまでOSから返ってこないため、エラーコードも見ることができず、原因の調べようがありません。 だいたい「catch (Exception e)」に来ずエラー中断するのは、そもそも.NETに問題があるようにも思われます。 私は下記のマイクロソフトのチュートリアルを参考にしました。 http://ja.gotdotnet.com/quickstart/default.aspx 「タスクの例」のネットワークを参考にしています。 当方は「Visual Studio.NET2003」を使っているのですが、Jubeiさんによると.NET2002では上記のエラーは生じないとのことですが、当方が参考にしているコードは.NET2002用なのでしょうか。 | ||||||||||||
|
投稿日時: 2004-01-12 17:20
諸農です。
なんと言えばいいんでしょうか。。(^^; なんか、たんなる言い掛かりの様にも思えてしまうんですが。。
VS2002、VS2003は、まったく関係ないと思いますよ。 下記のコードで、例外をトラップして、思い通りの再試行処理ができましたから。 #3回の再試行まで行ってダメだったら、通常のWindowsFormアプリケーションの #メッセージループに入ります。 環境としては、実行機および開発機がWin2000SP4、開発はVS2003(皆さんと同じですね)、 接続先として指定しているマシン(192.168.0.32)はウチのLAN環境上には存在していません。 つまり、サーバーが稼動していないのと同じ状況です。
コードの組み方(構造化例外とか、例外クラスのトラップの方法とか)を 見直してみられてはいかがですか? ではでは(^^)/ _________________ 諸農和岳 Powered by Borland Delphi/C++Builder & Microsoft VS.NET [ メッセージ編集済み 編集者: Jubei 編集日時 2004-01-12 19:13 ] | ||||||||||||
|
投稿日時: 2004-01-13 07:23
Jubeiさん、レスありがとうございます。
> 境としては、実行機および開発機がWin2000SP4、開発はVS2003(皆さんと > 同じですね)、 > 接続先として指定しているマシン(192.168.0.32)はウチのLAN環境上には > 存在していません。 > つまり、サーバーが稼動していないのと同じ状況です。 不思議です。これなら当方と同じ環境です。 こちらではこの環境で「catch (Exception e)」にひっかかってくれません。 唯一異なるのは、当方は「Windows XP HOME Edition」です。 「Windows XP HOME Edition」はIISが実装されていないということですが、Windowsアプリケーションの開発には関係ないと認識しています。 Jubeiさんに示していただいたコードは、try部は当方とまったく同じに見えます。 当方が作成したコードで異常が生じるだけではなく、下記のマイクロソフトのチュートリアルをそのまま実行しても、同じようにcatchでひっかかってくれず、強制終了します。 http://ja.gotdotnet.com/quickstart/default.aspx の「タスクの例クイック スタート」の「タスクの例 : TCPClient を使用して DateTime クライアントを作成する」のサンプルコードにおいて、DateTimeサーバ(ポート13)を禁止しているサーバに対しこのまま実行すると、やはりcatchでひっかかってくれず、強制終了します。 サーバのポート13を開いたり、許可されているポート番号に接続すると、問題なく動作します。 こちらのサンプルでは「catch (Exception e)」はないのですが、追加しても結果は同じです。 「Windows XP HOME Edition」が問題なのでしょうか。 | ||||||||||||
|
投稿日時: 2004-01-13 08:19
諸農です。
Exceptionで引っ掛けていません(^^; アップしたコードでは、SocketExceptionをキャッチするようにしておりますので、 一度、SocketExceptionを引っ掛けるようなテスト用のコードを作ってみてはいかがですか?
XP PROやWin2003はあるのですが、HOMEの環境がすぐに準備できないので 今すぐには検証することは出来ません。 申し訳ないです。 --編集補足です-- もしも、実行環境がHOME EDITIONでcatch(Exception ex)が使えないとなると、 多くの人から問題点の指摘が、既に多く寄せられているはずです。 マイクロソフトのFAQのサイトや障害報告のサイトで同じような現象の 報告がされていないか検索してみるのもひとつの手だと思います。 ただし、ウチの環境(Win2000)ではExceptionのみを捕捉するコードに 変更しても、期待通りの結果が得られましたことを、ここに報告しておきます。 --編集補足終わり-- _________________ 諸農和岳 Powered by Borland Delphi/C++Builder & Microsoft VS.NET [ メッセージ編集済み 編集者: Jubei 編集日時 2004-01-13 09:29 ] | ||||||||||||
|
投稿日時: 2004-01-13 08:51
諸農です。
確認ですが、「datetimeclient.cs」または「datetimeclient.vb」の 「コードを改編することなく」コマンドラインでコンパイルして、 作成された実行形式ファイルをコマンドプロンプトから実行されたんですよね? Connect()は例外保護のブロックに入っていないので、アプリケーションコードでは Connect()で発生するエラーを捕捉できません。 つまり、アプリケーションコードが異常終了するのは当然なんですけども。。。 もちろん、ウチの環境でもこのアプリケーションコードで試せば異常終了します。 それは、当然の結果です。チュートリアルで示されているアプリケーションコードが そのようになっているからです。 全体的に、何か勘違いされていませんか? それとも私が勘違いしているのでしょうか? --編集補足です--
お手数でなければ、そのコードをアップしてください。 --編集補足終わり-- _________________ 諸農和岳 Powered by Borland Delphi/C++Builder & Microsoft VS.NET [ メッセージ編集済み 編集者: Jubei 編集日時 2004-01-13 09:19 ] | ||||||||||||
|
投稿日時: 2004-01-13 12:46
少管閑事さんの(2004-01-12 09:39)では、
ということなので、Connect()は通っているようです。これは少管閑事さんの『プログラムが「GetStream」で中断するため、再試行に移行してくれません。』と一致すると思います。 諸農さんは、『Connect()は例外保護のブロックに入っていないので』と、Connect()できないところを見ていらっしゃいますから、対象としている場所が違っているようです。 サーバがない、サービスがない、という場合はConnect()が失敗し、サーバとサービスはあるが、ポートを閉鎖している(少管閑事さんの(2004-01-13 07:23)より)場合はConnect()は通り、GetStream()が例外を発生させる、ということなのでしょうか。 #ポートを禁止していても「サーバーがない」と同じになるのでは?とは、思うけど まず、「Connect()が通り、GetStream()が失敗する状況」をはっきりさせるべきではないでしょうか。 | ||||||||||||
|
投稿日時: 2004-01-13 13:31
こんにちわ。諸農です。
Jittaさん、いつもフォローをありがとうございますm(_ _)m
実はここが曲者だと思っています。 デバッグ実行していると、例外がIDE上で表示されますが、 その時、コードエディタ上では、Connectの(例外発生コードの)次の行で あるGetStreamが緑色の反転表示になって、まるでここで停止しているよう に見えるんですよね。 サーバーはあるけど、ファイアーウォールで接続を禁止している場合にも、 Connect()で例外は発生しますね。 例外クラスはSocketExceptionのままですが、メッセージの内容が 「対象のコンピュータによって拒否されたため、接続できませんでした。」 に変更されるぐらいですので、アプリケーションの例外捕捉コードで何らか の対処を行う必要性はないものと思われます。 少管閑事さんの言われているように、例外を捕捉することが出来ないんだ、 と言うことを検証するのであれば、テスト用のネットワークが無くても、 自分で呼び出した関数内からSocketExceptionをthrowすることで、 呼び出し側関数で例外を捕捉できるかどうかのテストは出来ると思うのです。 もしも、これで捕捉出来ないとなると、まさしくFCLとか言語とかコンパイラの バグなのでは?という疑いの方が濃厚になると思います。 なので、少管閑事さんが試された「タスクの例」のコードで、例外を捕捉出来な かったといわれる「改編後のコード」をアップしていただけたら、検証できるの になぁ。。といった感じでしょうか。 ではでは(^^)/ 編集補足です。 少管閑事さんのところで発生している例外はこれまでの投稿によれば 「SocketException」です。 対して、GetStream()で発生する例外は、MSDNやSDKによると 1.InvalidOperationException(TcpClientがリモートホストに接続されていません。) 2.ObjectDisposedException(TcpClientが閉じられています。) です。 少管閑事さんのところで例外を捕捉出来ないと言うのは、 やはりConnect()を例外保護していないコーディングが原因なのでは? と思われます。 _________________ 諸農和岳 Powered by Borland Delphi/C++Builder & Microsoft VS.NET [ メッセージ編集済み 編集者: Jubei 編集日時 2004-01-13 14:37 ] |