- PR -

Socket.Exceptionでハンドルされていない例外

投稿者投稿内容
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2004-01-11 08:02
諸農です。

引用:

御気楽堂さんの書き込み (2004-01-10 10:42) より:

勉強しなおして、このサンプルコードを理解し、
動かせるようになったらまたお邪魔します。



私の言葉がきつすぎたかもしれません。。
すみませんでした。

ただ、出直して来いというつもりはなく、
FCL1.0からFCL1.1へのコンバージョンで動かせるように
なるための情報交換は、継続してここのフォーラムで
やっていってもいいと思っています。

それは今後のプログラミングに向けての勉強になるのだと
思いますし、もう一つは、せっかく購入した書籍の、一つ
の活用方法だと思いますから。
#著者の名誉回復にもつながるのでは?

ではでは(^^)/
_________________
諸農和岳
Powered by Turbo Delphi & Microsoft Visual Studio 2005

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/
少管閑事
会議室デビュー日: 2003/10/17
投稿数: 8
投稿日時: 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用なのでしょうか。
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2004-01-12 17:20
諸農です。

引用:

少管閑事さんの書き込み (2004-01-12 09:39) より:

プログラムが「GetStream」で中断するため、再試行に移行してくれません。
デバッグウィンドウには「プログラム '[848] XXXXX.exe' はコード 0 (0x0) で終了しました。」と表示されます。

サーバが立ち上がっていれば問題なく動作します。
「GetStream」を呼び出してから数秒でエラーが発生するまでOSから返ってこないため、エラーコードも見ることができず、原因の調べようがありません。
だいたい「catch (Exception e)」に来ずエラー中断するのは、そもそも.NETに問題があるようにも思われます。



なんと言えばいいんでしょうか。。(^^;
なんか、たんなる言い掛かりの様にも思えてしまうんですが。。


引用:

当方は「Visual Studio.NET2003」を使っているのですが、Jubeiさんによると.NET2002では上記のエラーは生じないとのことですが、当方が参考にしているコードは.NET2002用なのでしょうか。



VS2002、VS2003は、まったく関係ないと思いますよ。
下記のコードで、例外をトラップして、思い通りの再試行処理ができましたから。
#3回の再試行まで行ってダメだったら、通常のWindowsFormアプリケーションの
#メッセージループに入ります。

環境としては、実行機および開発機がWin2000SP4、開発はVS2003(皆さんと同じですね)、
接続先として指定しているマシン(192.168.0.32)はウチのLAN環境上には存在していません。
つまり、サーバーが稼動していないのと同じ状況です。

コード:

private void button1_Click(object sender, System.EventArgs e)
{

TcpClient tcpClient = new TcpClient();
tcpClient.ReceiveTimeout = 10;
tcpClient.SendTimeout = 10;

int c = 0;
bool FLG = true;
do
{
try
{
IPAddress ip = IPAddress.Parse("192.168.0.32");
tcpClient.Connect(ip,32000);
NetworkStream networkStream = tcpClient.GetStream();
FLG = false;
}
catch(SocketException ex)
{
listBox1.Items.Add(ex.Message + ": CNT = " + c.ToString());
this.Update();
c++;
if (c > 2)
{
listBox1.Items.Add("再試行が3回を超えたので強制終了しました");
break;
}
}
catch(Exception ex)
{
listBox1.Items.Add(ex.Message);
break;
}
}while(FLG);
}




コードの組み方(構造化例外とか、例外クラスのトラップの方法とか)を
見直してみられてはいかがですか?


ではでは(^^)/

_________________
諸農和岳
Powered by Borland Delphi/C++Builder & Microsoft VS.NET

[ メッセージ編集済み 編集者: Jubei 編集日時 2004-01-12 19:13 ]
少管閑事
会議室デビュー日: 2003/10/17
投稿数: 8
投稿日時: 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」が問題なのでしょうか。
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2004-01-13 08:19
諸農です。

引用:

少管閑事さんの書き込み (2004-01-13 07:23) より:

こちらではこの環境で「catch (Exception e)」にひっかかってくれません。



Exceptionで引っ掛けていません(^^;
アップしたコードでは、SocketExceptionをキャッチするようにしておりますので、
一度、SocketExceptionを引っ掛けるようなテスト用のコードを作ってみてはいかがですか?

引用:

「Windows XP HOME Edition」が問題なのでしょうか。



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 ]
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2004-01-13 08:51
諸農です。

引用:

少管閑事さんの書き込み (2004-01-13 07:23) より:

当方が作成したコードで異常が生じるだけではなく、下記のマイクロソフトのチュートリアルをそのまま実行しても、同じようにcatchでひっかかってくれず、強制終了します。

http://ja.gotdotnet.com/quickstart/default.aspx
の「タスクの例クイック スタート」の「タスクの例 : TCPClient を使用して DateTime クライアントを作成する」のサンプルコードにおいて、DateTimeサーバ(ポート13)を禁止しているサーバに対しこのまま実行すると、やはりcatchでひっかかってくれず、強制終了します。



確認ですが、「datetimeclient.cs」または「datetimeclient.vb」の
「コードを改編することなく」コマンドラインでコンパイルして、
作成された実行形式ファイルをコマンドプロンプトから実行されたんですよね?

Connect()は例外保護のブロックに入っていないので、アプリケーションコードでは
Connect()で発生するエラーを捕捉できません。
つまり、アプリケーションコードが異常終了するのは当然なんですけども。。。
もちろん、ウチの環境でもこのアプリケーションコードで試せば異常終了します。
それは、当然の結果です。チュートリアルで示されているアプリケーションコードが
そのようになっているからです。

全体的に、何か勘違いされていませんか?
それとも私が勘違いしているのでしょうか?

--編集補足です--
引用:
こちらのサンプルでは「catch (Exception e)」はないのですが、追加しても結果は同じです。



お手数でなければ、そのコードをアップしてください。

--編集補足終わり--


_________________
諸農和岳
Powered by Borland Delphi/C++Builder & Microsoft VS.NET

[ メッセージ編集済み 編集者: Jubei 編集日時 2004-01-13 09:19 ]
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-01-13 12:46
引用:

Jubeiさんの書き込み (2004-01-13 08:51) より:

全体的に、何か勘違いされていませんか?
それとも私が勘違いしているのでしょうか?


 少管閑事さんの(2004-01-12 09:39)では、
引用:

'System.Net.Sockets.SocketException' のハンドルされていない例外がsystem.dll で発生しました。

追加情報 : 接続済みの呼び出し先が一定の時間を過ぎても正しく応答しなかったため、接続できませんでした。または接続済みのホストが応答しなかったため、確立された接続は失敗しました。


ということなので、Connect()は通っているようです。これは少管閑事さんの『プログラムが「GetStream」で中断するため、再試行に移行してくれません。』と一致すると思います。

 諸農さんは、『Connect()は例外保護のブロックに入っていないので』と、Connect()できないところを見ていらっしゃいますから、対象としている場所が違っているようです。

 サーバがない、サービスがない、という場合はConnect()が失敗し、サーバとサービスはあるが、ポートを閉鎖している(少管閑事さんの(2004-01-13 07:23)より)場合はConnect()は通り、GetStream()が例外を発生させる、ということなのでしょうか。
#ポートを禁止していても「サーバーがない」と同じになるのでは?とは、思うけど


 まず、「Connect()が通り、GetStream()が失敗する状況」をはっきりさせるべきではないでしょうか。
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2004-01-13 13:31
こんにちわ。諸農です。

Jittaさん、いつもフォローをありがとうございますm(_ _)m

引用:

ということなので、Connect()は通っているようです。これは少管閑事さんの『プログラムが「GetStream」で中断するため、再試行に移行してくれません。』と一致すると思います。



実はここが曲者だと思っています。

デバッグ実行していると、例外が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 ]

スキルアップ/キャリアアップ(JOB@IT)