書き込みの回数が多く申し訳ないですが、
またまた教えて頂けたらと思います。
ネットワークでホスト名が存在するかどうかを判別したく、
下記のようなソースを書きました。(一部抜粋)
bool FindHost(const char *host)
{
HOSTENT *lphost = NULL;
WSADATA wsa;
WSAStartup(MAKEWORD(1, 1), &wsa);
lphost = gethostbyname(host);
if (lphost == NULL){
WSACleanup();
return false;
}
WSACleanup();
return true;
}
問題なくホスト名からの検索はできるのですが、
一度検索したホスト側のPCをネットワークからはずし(LAN抜いただけです)
再度検索をかけたところ、繋がらないはずなのになぜかホスト名が見つかってしまいます。(lphostがNULLでないという判定だけですが)
存在しないホスト名を指定するとちゃんと認識しませんし、
一旦PCを再起動するとLANに繋がっていないPCは認識しません。
(一度繋ぐとLANを抜いてもやはり認識しっぱなしですが。。。)
結果を見た限りでは一度繋げたホスト名の情報がキャッシュに残り、
ホスト名を参照した時に、存在しないのでキャッシュから情報を取得しているのでは
ないか?という、自分勝手な認識です。
これの原因はどこにあるのでしょうか?
また、解決するにはどうすればいいのでしょうか?
ご教授頂けたらと思います。
よろしくお願いします。
> これの原因はどこにあるのでしょうか?
処理自体は仕様通りの正しい挙動だと思いますが、使い方が間違ってます。
<MSDN>
The gethostbyname function retrieves host information corresponding
to a host name from a host database.
</MSDN>
gethostbyname は、本来「データベースから」情報を取得する関数です。
実際にそのホスト名をもつマシンがあるかないかの判定には使えません。
ローカルに hosts を用意するだけでも情報は取得できてしまうはずです。
Banさんありがとうございます。
なるほど。本来の使い方自体を誤っていたわけですね。
特定のホスト名をもつPCを検索するのに適したAPI・関数はあるのでしょうか?
#さらに質問しておいてなんですが
#この質問に関する回答は頂ければうれしいですが
#特に必要ないと解釈して下さい。
#ちょっと自分で探してみます。。。
ので、解決とさせて頂きます。
ありがとうございました。
そもそも「検索する」ことに意味があるかどうかが検討課題でしょう。
http サービスなり MS-NETWORKS サービスなりを使うための前提として
ホストを探す、っつーのは根本的な誤りです。
使いたい機能で直接つなぎに行くのが正しい態度というものでしょう。
セキュリティ面でも...
tetrapodさん回答ありがとうございます。
ホスト名の検索についての目的なのですが、
ローカルで接続したPCに対してこれを行いたいと思っています。
(httpとか大規模なものなど到底orz)
動機に関しては指定のホストがローカルで接続されているかどうかを
どうやったら調べられるんだろう?程度のものですが。。。
# 本題ではないですが、
bool FindHost(const char *host)
{
HOSTENT *lphost = NULL;
WSADATA wsa;
WSAStartup(MAKEWORD(1, 1), &wsa); // エラーチェックはした方が。
lphost = gethostbyname(host);
WSACleanup(); // 常に実行するならこの順番で書けばいいような。
return lphost == NULL;
}
って、送った瞬間に気づきましたが、
>(一部抜粋)
なんですね.....見落としてましたorz
# 瞬間....?って直後か。ダメっぽい...orz
Banさん的確なご指摘ありがとうございます。
↑の文は簡易にしたものなので
一応エラーチェックは入れてあります。
また順番は確かにご指摘の通りのほうがよいですね^^;
ちょっと本題に戻ってしまうのですが、
結局あれから別API等を探してみたのですが見つからず
ホスト名からではなくIPからの検索に変えてみたりと色々自分なりに策を練ってみたのですが、結果同じになってしまいました。。。
(うまく検索相手PCは見つかりますが、一度見つけてしまうと
その相手がネットワークからはずれても見つけてしまいます。)
引き続き自分なりに他の方法を探してみますが、
接続相手がネットワークに存在するか、また相手がネットワークからはずれた場合に
それを認知できる方法があれば教えて頂きたいと思います。
回答いらないといっときながら申し訳ないです。。。
まず
>接続相手がネットワークに存在するか、
というのがどういうことか定義することからはじめる必要があります。
TCP,UDP/IP しか考えないのか? IPX/SPX の類は考えなくていいのか?
セキュリティ強化のため特定のポートしか開けてないマシンは「存在」なのか?
こういう話題になると脊髄反射的に ping 打って返事があれば...
と答えたくなりますが、それでいいのかどうかは仕様次第。
B-FLETS の ROUTER を導入して「インターネット接続」は共有している、つまり
複数代のマシンが家庭内 LAN につながっているけど、
各マシン同士は相互に通信しない/できない設定、なんてのは
ウィルス対策ソフト・ファイアウォールの設定でいくらでも作れます。
だから「まさに通信したい、そのプロトコルで返事があるかどうか」
以外に解はないと思うのですけど、いかがなものでしょうか。
tetrapodさん回答ありがとうございます。
とりあえずはTCP/IPのみでUDPやIPX/SPXはいいかなと。
ポートの制限も特に厳しくはしていません。(ある程度メジャーなものはしていますが)
ただ、ルータやFW関係等様々絡んでくるとなると私の力ではなんとも。。。
ping自体は問題なく返ってはくるのですが。
↑ソースの通り、
gethostbynameやgethostbyaddr等でPCの情報は取得できるので特に厳しい環境ではないかと思います。
ひょっとして私がやろうとしてることはややこしい問題なのでしょうか...?
いや、結局のところ何がしたいのかが不明なのです。だから
>>接続相手がネットワークに存在するか、
>というのがどういうことか定義することからはじめる必要があります。
ということなのですが。
gethostbyname 類は名前解決のための関数。
名前解決できればそれでいいのか?
IP アドレスが既知な状態で(名前解決済みで)そいつが居るかどうか調べたい?
なら脊髄反射レスですが ping 打ってみればいい。
ただしセキュリティソフト類が ping に反応しない設定してることは普通にあります。
そーいうのを「存在しない」と判定していいのか?
匿名希望様のローカルな環境でのみ動けばいいのか。
セキュリティの厳しい設定がされている客先でも動かねばならんのか。
そもそも「ローカルなホスト」って何を意図してるのか?
問題定義から入らんとなんとも言いようが無いです。
tetrapodさん度々返答ありがとうございます。
説明不足で申し訳ないですorz
>IP アドレスが既知な状態で(名前解決済みで)そいつが居るかどうか調べた>い?
まさにその通りです。
>なら脊髄反射レスですが ping 打ってみればいい。
まさにプログラム内でそれを行いたいのです。
>ただしセキュリティソフト類が ping に反応しない設定してることは普通に
>あります。
>そーいうのを「存在しない」と判定していいのか?
問題ないです。というか、「セキュリティの問題でpingが反応しない」ということがないのは実証済みです。また、汎用性を持たせるわけではなく、あくまで現在自分が使っている環境のみで動けば問題ないです。
>そもそも「ローカルなホスト」って何を意図してるのか?
意味わからなくて申し訳ないです。。。
なんといったらいいのかよくわからないのですが、
小さなWANといった感じでしょうか?
自分のPC Onlyを指しているのではないです。
10数台のPCでのWAN(と、呼んでいいのかわからないですが)になります。
「ローカル」と言う表現が非常に紛らわしかったと思います。
↑で私が示している「ローカル」は自PCではなく、(ここが紛らわしかったです)
WANで繋がっている他PCになります。(ローカルで組んでいるネットワークっていう表現のほうがわかりやすいのだろうか...)
以上の説明で大丈夫でしょうか・・・?
よろしくお願いします。
全部解説する元気は無いので例えば
http://www.pc-view.net/Network/030610/
>小さなWANといった感じでしょうか?
ふつーはそれを LAN といいます (爆)
G/W の内側、つまり NETMASK=1 の部分が全て同一なマシン群
ということでしょうか。
tetrapodさん長々とお付き合い頂きありがとうございます。
>ふつーはそれを LAN といいます (爆)
なるほど(笑
>G/W の内側、つまり NETMASK=1 の部分が全て同一なマシン群
>ということでしょうか。
えっと。G/Wが同じということでしょうか?^^;
そうであれば「同一なマシン群」になります。
リンク貼って頂いてるHP参照しました。
まさにやりたいことであります。ありがとうございます。
リンク先の後編に期待してますが、ここまで解説あれば自力でなんとか作れそうな気がします。
確かに相手にこちらからメッセージを流してそれが返ってくるかどうか確かめてやればいいだけですよね。。。
pingを見てれば十分わかりうるものだったのにちょっと自分の発想力の乏しさに悲しくなりました...
HP検索も「ping」「作成」とかで検索すればよかったですね。
そこらへんもがんばって磨いていきたいと思います。
また結果を報告したいと思います。
ありがとうございました。
なんとなくこんなページを紹介などしてみましょう。
http://www.kt.rim.or.jp/~ksk/wskfaq-ja/examples/
んで追記とか。
本来 ping ってのはネットワークのトラブルシューティングのため*だけ*に
使うべきものであって、これを常時使ってマシンの存在チェックする、なんてのは
ネットワークトラフィックを増やすだけ、愚の骨頂です。
# なんとかってワームを思い出します。
最初からそう書いているのですが耳を貸してくれないようですし...
「使いたいプロトコルを使いたい相手に直接投げる」のが基本中の基本。
余計なことはしないのが一番です。
# ping というか ICMP を、技術的興味で使ってみたいのなら止めませんが。
tetrapodさんありがとうございます。
リンク参考にさせて頂きます。
>ネットワークトラフィックを増やすだけ、愚の骨頂です。
たしかに...負担かかるだけなのはわかってはいるんですけどorz
>最初からそう書いているのですが耳を貸してくれないようですし...
わかってはいるんです...ただ、なんていうか...やりたいだけです。
後、常時マシンチェックをするわけではないんです。
プログラムを実行した時に一回だけ行えればいいんです。
↑の流れからもお察しとは思いますが
ネットワークに関して詳しくないもので。。。
特にややこしいことする気はないです。
これだけできたらあんまり余計なことはしないようにします。
ログをさらっと読んだだけなので、微妙に論点が違ってるかもしれません。(爆
要するに、現在LANに接続されているコンピュータの情報が得たいわけですよね?
tetrapodさんが言うように、つなぎたいプロトコルでつなぎにいけばいいのかと。
connect()を使って接続してみて、connect()がSOCKET_ERRORを返せばホストは存在しない、正常に接続できれば存在している、ってことになるのでは?
こんな感じではだめなんでしょうか。
うぃろさん回答ありがとうございます。
>connect()を使って接続してみて、connect()がSOCKET_ERRORを返せばホスト>は存在しない、正常に接続できれば存在している、ってことになるのでは?
>こんな感じではだめなんでしょうか。
問題ないです。
おっしゃるとおりにホストが存在するかの有無だけ確認できればいいので。
確かにうぃろさんのおっしゃる通りの方法で問題ないかと思います^^
ありがとうございます。
ツイート | ![]() |