ネットワークドライブ再接続時にエラーが発生する

[戻る]
ふぁっきー 2007/03/22(木) 10:39:50
ネットワークドライブ再接続時にエラーが発生する件について、
現象が回避できず解決策も見つからず困っております。
皆様のお知恵をお借りできないでしょうか。。。

【環境】
サーバ   :Win XP (SP2)
クライアント:Win XP (SP2)
使用言語  :VC++ 6.0

【現象】
ある一定の間隔(1sec程度)で、ネットワークドライブのアクセスチェックを行うプログラムを
作成したのですが、プログラムを動作させ続けたまま何もPCを操作せずに、置いておくと
1日程度経過後にそのチェックでエラーが発生してしまいます。再接続の仕組みを入れてはいる
のですが、復旧できていませんでした。

【コーディング内容】
・ネットワークドライブのアクセスチェック処理
1._chdrive及び_chdir関数を使用し、ネットワークドライブのアクセスチェック及び
  ネットワークドライブ上のディレクトリにアクセスできるかチェックを行います。
2.1.の結果、-1がリターンされてきた場合、再接続処理を行う。

・ネットワークドライブ再接続処理
1.WNetGetConnection関数を使用し、ネットワークパスの取得を行います。
2.NETRESOURCE構造体(仮に変数をaとします。)に値をセットします。

  a.dwType = RESOURCETYPE_DISK;
  a.lpLocalName = localDriveName.GetBuffer(0);
  a.lpRemoteName = chrRemote;
  a.lpProvider = NULL;

3.WNetAddConnection2関数を使用し、再接続を行います。

  WNetAddConnection2(&nr,
           NULL,
             NULL,
             0);

ネットワークドライブ再接続時にエラーが出る場合は、WNetAddConnection2関数の戻り値が
ERROR_ALREADY_ASSIGNED(既に接続済み)となっていました。

以上、宜しくお願い致します。

tetrapod 2007/03/22(木) 10:56:58
症状だけから判断すると典型的リソースリークです。
ハンドル数とかが無制限に増えていないかどうかをチェック。

ふぁっきー 2007/03/22(木) 11:20:58
tetrapod様、ご回答ありがとう御座います。

確かに、この症状が発生するとメモリ消費が激しくなり、最終的にはアプリケーションが
ダウンしてしまいます。

どのハンドルが怪しそうか、教えて頂けないでしょうか。
※質問ばかりで、申し訳ありません。

以上、宜しくお願い致します。

tetrapod 2007/03/22(木) 12:46:02
ソース無いのにどれが怪しいかなんて俺らにわかるわけないぢゃん。
そんなのは自分で調べておくんなまし。
Open してるけど Close してないのがあれば、それが原因。
ソース開示するからデバッグしてってのはお断り。

コーディング以前の話として仕様レベルでおかしいと思う。
1秒に1回アクセスなんてトラフィック量を増大させるだけで無駄っぽいし、
そもそもアクセスできない=切断された とは限らないよ。
だから再接続しに行くこと自体がヘン。

ITO 2007/03/22(木) 13:14:41
 
 ネットワークドライブのアクセスチェックのためだけにソフトでネットワーク接続
をしなければ駄目ですか?
 ネットワークドライブのアクセスチェックが完了して処理のためならわかりますが
ソフトで使うネットワークドライブですからマニュアルもしくはiniファイルやレジストリー
登録するぐらいに決まっているはずですよね。
 WINDOWSのOSレベルできちんとネットワークドライブとして登録振れば、普通の
ディレクトリー検索でチェックできるのと思います。

PATIO 2007/03/22(木) 13:26:52
多分、ここで出てきている話は、\\の後にPCの名称を指定して接続するような接続の仕方
かなぁと思うんですが、
ローカルデバイスと違ってネットワーク先のデバイスの場合、必ず接続できると言う
類のものではありませんし、ネットワークの構成によっては接続数の上限等の関係で
アクセスできなくなることもありえると思います。
GATEWAYが限られたリソースを有効活用するために使用していない接続を切って
他の接続の為に回すなんて事もありえるでしょうし。
なので必ず接続できると言う類のものではないし、必ず利用できるデバイスと言う
わけでも無いという事を前提に設計しておかないといけないと思います。
接続できないとシステムとして成立しないような設計をしているならそれがそもそもまず
いと思います。
そういう意味で仕様的にもっと考え直す必要があると思います。

ふぁっきー 2007/03/22(木) 13:27:34
tetrapod様、ご回答ありがとう御座います。

>Open してるけど Close してないのがあれば、それが原因。
特別に何かをOpenしたりはしておりません。

>ソース開示するからデバッグしてってのはお断り。
それは確かに仰るとおりだと思っています。
※デバックまでお願いしたら、私の仕事がなくなってしまいますし。
WNetGetConnection、WNetAddConnection2の使用方法が間違っているのかと思い、
先程のご質問をさせて頂きました。(後処理等が抜けている等。)

>そもそもアクセスできない=切断された とは限らないよ。
>だから再接続しに行くこと自体がヘン。
そうだったんですか・・・
・・・と言う事は、アクセスできない要因が切断以外にもあると言う事ですよね。
ディスクにアクセスできない = ドライブを認識していない(切断?)と思っていました。
_chdrive及び_chdir関数を実行するとエラーとなる、他の要因として
どのような事があるのでしょうか?
※MSDNには、エラーの時は-1しか書いてなかったので・・・

先程ネット検索をしていたら、XPの機能として
「ログオン時間の有効期間が切れるとクライアントを切断する」の記事を見つけました。
これの影響で切れている可能性もあるのではとも考えていますが、断言できないのが痛い所で
す。

ふぁっきー 2007/03/22(木) 13:45:12
ITO様、ご回答ありがとう御座います。

> ネットワークドライブのアクセスチェックのためだけにソフトでネットワーク接続
>をしなければ駄目ですか?

元々、手動でサーバ側にはネットワークドライブを割り付けています。
しかし、エラーケースとしてアプリケーション動作中に何らかの要因で
ネットワークドライブ先のファイルにアクセスできなくなった事を想定し、
再接続させる仕組みを組み込んでおります。

※現在のコーディングはネットワークドライブ先のファイルアクセスを行うたびに、
 必ず_chdrive及び_chdir関数を呼び出しています。
 この仕組みは、ファイルOPENに失敗した時のみに変更しようと考えております。

tetrapod 2007/03/22(木) 14:12:58
権限が無い (途中で剥奪された) とか
ファイル存在を確認→→→→→→→→→→→ファイルオープンは失敗とか
          別ユーザにより削除
ネットワーク的に物理的障害が発生してると
ファイルオープンが失敗するけど、再接続も失敗するとか
接続に1秒以上の時間を要すると多重に接続しないだろうかとか

ぱっと思いつく程度でこれくらいはある。
真剣に考えればもっともっとありそうだしね。

ウチでは samba server のネットワーク接続において、
無アクセス時間10分でセッション自動切断を設定してる
smb.conf : deadtime=10
でも、ふつーはアクセスしようとしただけで自動的に再接続される
例 : CreateFile で \\Server\share\file を開こうとするだけで再接続される
例 : chdir しようとするだけで再接続される
し、この設定で今まで問題出たこと無いんだけどな。

自分での再接続が本当に必要なの?

ふぁっきー 2007/03/22(木) 14:35:18
PATIO様、ご回答ありがとう御座います。

>接続できないとシステムとして成立しないような設計をしているならそれがそもそもまず
>いと思います。

その通りだと思います。3年前から動いているシステムの為、あまり深くは考えずに
動いているから大丈夫だろうと思っていましたが、色々不味い点があったようです。

>そういう意味で仕様的にもっと考え直す必要があると思います。

確かに、仕様から見直す必要がありそうなのですが、
既にアプリケーションを納品してしまった為、
1から仕様を見直すのは難しい状況です。

ふぁっきー 2007/03/22(木) 16:47:00
tetrapod様、ご回答ありがとう御座います。

>権限が無い (途中で剥奪された) とか
>ファイル存在を確認→→→→→→→→→→→ファイルオープンは失敗とか
>          別ユーザにより削除
>ネットワーク的に物理的障害が発生してると
>ファイルオープンが失敗するけど、再接続も失敗するとか
>接続に1秒以上の時間を要すると多重に接続しないだろうかとか
確かに、上げて頂いた中にも発生しそうな問題がいくつかあります。
この現象発生時に、まずネットワーク的に物理的障害があったのではと考えて、
Hubの交換を行いました。
数日間は何も起こりませんでしたが、再度現象が発生した為に
アプリケーション側に問題がありそうだという事で調査を始めました。

>でも、ふつーはアクセスしようとしただけで自動的に再接続される
>例 : CreateFile で \\Server\share\file を開こうとするだけで再接続される
>例 : chdir しようとするだけで再接続される
>し、この設定で今まで問題出たこと無いんだけどな。
>
>自分での再接続が本当に必要なの?
この仕組みを作成する以前に、ネットワークドライブ先を指定してchdirやCreateFileを
実行するとエラーが発生するパターンがありました。
※エラー発生時、エクスプローラ上ではネットワークドライブに「X」表示がされていました。

打合せの結果、「ネットワークドライブが切れていると認識している為にエラーと
なっているのではないか?ネットワークドライブの再接続処理等が必要なのではないか?」
と言う方向に話が進み、この機能を実装する事になりました。

この機能を実装後、エクスプローラ上でネットワークドライブに「X」表示がされていても
問題なく動作するようになったのですが、今回の現象が発生するようになりました。

2007/03/22(木) 22:35:52
>特別に何かをOpenしたりはしておりません。
Connectは、ある意味Openと同じことです。
大抵の処理は、後始末まで考えておくべきでしょう。
まして、この場合は1OSどころかネットワークに接続する全て端末に影響する操
作です。
下手を打つと何が起こるかわからない処理である以上から慎重すぎるほど慎重
にやっても損は無いと思います。

気になるのは、エラーが帰ってきたから、「”とりあえず”再接続」という考え方で
す。
自分のパソコンの中だけで動かすならそれも許されるかも知れませんが、貴方の
口ぶりだと仕事です。
「とりあえずこうしたら動いたけど、別の場所が駄目になった」、では洒落にならな
いと思いますが、どうなんでしょうか。

>※エラー発生時、エクスプローラ上ではネットワークドライブに「X」表示がされて
いました。
エラーが出て、復帰処理をするのならば、エラーの詳細を調べるのが当然だと思
うのですが、調べましたか?
まさかOSのGUIでエラーを確認できているのに調べていないなどということは無い
ですよね?

またWNetGetLastErrorと言うAPIもあり、ネットワークでエラーが出ているのなら
ば真っ先に使うべきAPIだと思うのですが、その点についても言及されていないよう
です。

使ったのならその結果も併せて書いたほうが有効な回答が得られるでしょう。

使っていないのならエラー処理の仕方を根本から学んだほうがいいと思います
が。

PATIO 2007/03/23(金) 14:46:25
ふと思ったんですが、ネットワークドライブを提供している側のOSが
サーバーライセンスでない場合、同時接続数として許されるのは5ユーザーとか
かなり少なかったと思います。なので同時部複数のユーザーがアクセスしてしまうと
アクセスできなかったりする事もあったと思います。
そういったネットワークを使うが故の制限と言うのが出てきてしまうのは
致し方ない話なのでそこまで考えに入れた対処が必要だと思いますね。
同時アクセス数の制限の場合はいくら接続しようとしても空きが出ない限り
無駄だと思いますし。

Ban 2007/03/25(日) 13:16:25
> サーバーライセンスでない場合、同時接続数として許されるのは5ユーザーとか
> かなり少なかったと思います。

XP Proで10ユーザ、XP Homeで5ユーザですね。
# クライアント用なのでまぁそんなものかと思いますが。

ネットワークドライブの接続以外の接続などもあれば、それも含んだ値のはずで、
しかも、キャッシュなどの関係か、接続を切ったからといって直に解放されるわけではないらしい。
# 正式な仕様は知らないですが…どこかで解放タイミングは公開してるのでしょうか>識者の方々

毎秒接続なんてやってたら確かにこいつに引っかかる可能性はありそう…?

とーりすがり 2007/03/25(日) 18:40:13
サーバーはCAL数以上の接続できるのかな?

PATIO 2007/03/26(月) 10:38:19
クライアント側にライセンスを持たせる方式なら
クライアント側にライセンスがあれば問題無いのではないかと。
サーバーのライセンスで設定する場合は多分クライアントと同じ事になるかと思います。
但し、クライアントOSを違って枠的にはもっと余裕があったと思いますけれど。

Ban 2007/03/26(月) 14:14:24
> クライアント側にライセンスを持たせる方式なら
> クライアント側にライセンスがあれば問題無いのではないかと。
> サーバーのライセンスで設定する場合は多分クライアントと同じ事になるかと思います。
> 但し、クライアントOSを違って枠的にはもっと余裕があったと思いますけれど。

ごめんなさい、言わんとするところの意味が理解できず。
# 「クライアント」「サーバ」等の用語理解が文脈でズレてるのかも。

「クライアントにライセンスを持たせる方式」というのは、Win2000SやWin2003S等のCALですか。
「サーバーのライセンスで設定する場合」というのは、
サーバに(XPではなく)2000Sや2003Sを使った場合ということですか。

> 【環境】
> サーバ   :Win XP (SP2)

そもそもWindows XPはクライアント用OSで、サーバ用途に使うようにできてないので、
ライセンス上の問題のほか、動作制限としてもXP Proで10、Homeで5本の接続までになってて、
「CALがどうこう」とかでこの制限が緩和したりはしなかったと思いますが、
そういうことではなくてですか。

# とーりすがり さんの質問は、2000Sとか2003Sでの別ケースについてだと思いますが、
# こちらについての解答でしょうか。

PATIO 2007/03/26(月) 16:29:25
>「クライアントにライセンスを持たせる方式」というのは、Win2000SやWin2003S等のCAL
> ですか。
>「サーバーのライセンスで設定する場合」というのは、
> サーバに(XPではなく)2000Sや2003Sを使った場合ということですか。

そういう感じの話です。
CALでサーバーOSにアクセスする場合は、
その場合はサーバーOSにアクセスする側のクライアントにCALがあれば良いと言う
そのまんま当たり前の話です。(対象はあくまでもサーバーOS)
で、昔ながらのサーバーOS側に同時アクセス数を設定する方法だと
やっぱり上限があるでしょうという話。
ただ、サーバーの場合は端から多数アクセスを想定しているから上限が
クライアントOSより多いはずなので少しはましでしょという話です。
要は極当たり前の話を繰り返しているだけですね。

クライアントOSに対してガンガン同時アクセスするような作りを想定する事自体
間違っているわけでちゃんとその分を確保したければ、サーバーOSを使用しなさい
という話です。

> とーりすがり さんの質問は、2000Sとか2003Sでの別ケースについてだと思いますが、
> こちらについての解答でしょうか。
回答にはなっていないですね。
要はCALを採用しているサーバーOSであれば、クライアント側にCALがあれば、
サーバーOS側のライセンス上の制限は無いと思いますけれど、
リソースなんかの問題で上限と言うのはあるのではないかなぁと。
実際に試したわけではないので意味が無いといわれればそうですけれど。

ITO 2007/03/27(火) 18:58:33
知っている範囲では、
   クライアント = 顧客
   サーバー   = サービスから由来、
            顧客に対していろいろなサービスを行う
            (いろいろな情報を提供する)
という意味です。

>その通りだと思います。3年前から動いているシステムの為、あまり深くは考えずに
>動いているから大丈夫だろうと思っていましたが、色々不味い点があったようです。
サ-バーOSとクライアントOSが何を使っているかによっても変わると思います。

 ともかく、
   サーバー側で許可していれば、「WNetGetConnection関数」を使わなくてもネット
    ワークドライブが使える。
   「WNetGetConnection関数」は繋がってなく、途中からサーバーが許可した
    場合に限る。
 だと思います。
  とういうことが出来るように、システムを  安定させることから
 始めたほうがいいです。
 WNetGetConnection関数を使わなくてもCreateFile関数等でもいいはずです。
 #サーバーが特定のクライアントのみ許可している場合はありうるのかな?

Ban 2007/03/27(火) 19:10:21
> PATIOさん
# ご返信ありがとうございます。直接的な回答ではないということであれば了解です。

> ITOさん

>    クライアント = 顧客
>   サーバー   = サービスから由来、顧客に対していろいろなサービスを行う
いや、そういう一般的な話ではなく「文脈上で用語定義にブレ/ズレがあるかも」という話なので…。

# client(依頼するもの)とserver(応えるもの)であって「serviceに由来」という表現は微妙では
…?
# serverはserveの動詞形でserviceは名詞で…

> サ-バーOSとクライアントOSが何を使っているかによっても変わると思います。
これは最初の回答に【環境】として書かれているかと。(ProかHomeかは不明ですが)

ITO 2007/03/27(火) 19:40:38
>いや、そういう一般的な話ではなく「文脈上で用語定義にブレ/ズレがあるかも」
>という話なので…。
了解しました。

># client(依頼するもの)とserver(応えるもの)であって「serviceに由来」という表現
>は微妙では…?
># serverはserveの動詞形でserviceは名詞で…
確かにそうです。

>これは最初の回答に【環境】として書かれているかと。(ProかHomeかは不明ですが)

> サーバ   :Win XP (SP2)
> クライアント:Win XP (SP2)
見落してました。
クライアント同士の接続ですね。
ということは、最初に立ち上がったXP ProのPCがサーバー役として動作すること
になりますね。
XP Homeは、XP Proが動作していてネットワークが確立している状況でないとつながらな
いということですね。



 

Ban 2007/03/27(火) 19:49:34
> クライアント同士の接続ですね。

御意

> ということは、最初に立ち上がったXP ProのPCがサーバー役として動作することになりますね。

いや、スレ主からはProとHomeの限定がないので、Proがサーバ役か否かは外野には特定不能、
HomeかもしれませんしProかもしれません。

なので、Homeをサーバ役にしてると「全部で5本以上つながらない問題がある」とか、
そういう話になってます。
# これについてはスレ主さんが環境を書いてくれれば憶測の必要は無くなるわけですが。

ITO 2007/03/27(火) 20:55:06
>なので、Homeをサーバ役にしてると「全部で5本以上つながらない問題がある」とか、
たしか、Homeはサーバ役になれなかったはず。
Homeを先に立上げると繋がらない可能性があると思う。

古いスレッドには追加発言できません。