• 締切済み

gethostbynameを使うとエラーが出る

VC++2010EEを用いています デバッグすると出力画面に 'C:\Windows\SysWOW64\rasadhlp.dll' を読み込みました。Cannot find or open the PDB file このような感じのが沢山出てしまいます。(違うdllがいくつも) gethostbynameをコメントアウトするとそのようなエラーは出ません。 しかし、ホスト名からIPアドレスを取得したいのでどうしてもこれを用いたいです。 どうしたらよいのでしょうか?

みんなの回答

回答No.10

もし gethostbyname の引数にホスト名でなく "localhost" を指定したらうまく接続できるのであれば、ループバックでの接続はできてるので、ネットワークの設定の方がおかしいということになりそうです。 質問者さんの自宅(?)のブロードバンドルータに対してDDNSでホスト名を割り当てており、そのホスト名経由で、自身のPC内で動くサーバに接続したいということでよいでしょうか。一応、それ前提で話を進めますと… まず、ホスト名が正しくルータのグローバル側に割り当てられていることを確認しておく必要があります。グローバルIPアドレスを確認できる以下のようなサイト http://www.cman.jp/network/support/go_access.cgi で表示されたIPアドレスと、gethostbyname で取得されているIPアドレスが同じであることを確認します。同じであればアドレス解決は正しく行われています。 次に、ブロードバンドルータのポート解放と、そのポートへのTCP接続をあなたのPCに転送する(ポートマッピング)設定を行う必要があります。この辺りはすでにやってるでしょうか…? 転送先IPアドレスにはあなたのPCのアドレス(プライベートIPアドレス)を指定する必要がありますが、正しく設定できていますか? また、ルータの機種によっては転送先のポート番号を別のものにできたりする場合もあるかと思いますが、混乱しないよう同じ番号にしておくのがよさそう。 さらに、ブロードバンドルータのパケットフィルタリングで遮断するように設定されているポートは接続できないので注意が必要です。同様に、PC側のファイヤウォールやセキュリティソフトの設定も確認して、そのポートへのアクセスを遮断しないようにする必要があります(危険を承知で一時的に全部OFFにするという手も)。

  • wormhole
  • ベストアンサー率28% (1626/5665)
回答No.9

>いえ、グローバルIP?であることは確かなので大丈夫なはず・・・・・です なぜ疑問符・・・ >というか、ダイナミックDNSって非固定のグローバルIPをホスト名にリンクさせるやつだと思ったのですが #3の補足だとループバックアドレスを書かれていましたし、 >server.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); どういったアドレスを設定されてたのかは書かれていませんでしたので。 >inet_addr()の方でよろしければどちらも0でした gethostbyname()のときのをたずねられてるんだと思いますけど。

Null0lluN
質問者

補足

gethostbyname()ではconnectを抜けてくれないので不明です。 ちなみに、ホスト名とIPアドレスが一致してない可能性に思い当たり確認してみましたがきちんと一致していました

  • Wr5
  • ベストアンサー率53% (2173/4061)
回答No.8

>ネットまでいったん出してからPCに戻すという方法は可能です NATループバックに対応していることは確認済みでしたか。 connect()の戻り値とWSAGetLastError()の戻り値はいくつですかね?

Null0lluN
質問者

補足

inet_addr()の方でよろしければどちらも0でした

  • wormhole
  • ベストアンサー率28% (1626/5665)
回答No.7

>一応、ポートを解放しているのでネットまでいったん出してからPCに戻すという方法は可能です(ホスト名を使わないでアドレスを直接inet_addr()で入れるとちゃんと通信できる) 「inet_addr()で入れる」というのはLAN内のアドレスではないですか? #6でもいわれてますがLAN内部からWAN側のアドレスでLAN内にアクセスするにはポート開放だけではなくルーターがNATループバックをサポートしていないとできません。

Null0lluN
質問者

補足

>「inet_addr()で入れる」というのはLAN内のアドレスではないですか? いえ、グローバルIP?であることは確かなので大丈夫なはず・・・・・です というか、ダイナミックDNSって非固定のグローバルIPをホスト名にリンクさせるやつだと思ったのですが

  • Wr5
  • ベストアンサー率53% (2173/4061)
回答No.6

>ただ、h_addr_listの値が 0x00625284 "|esonline.ddo.jp" 紛らわしいですが、一応取得はできているようです。 # こちらでも確認はしましたが。 型が「char FAR * FAR * 」なので、ローカル変数でのウオッチでは正しく表示できないだけでしょう。 メモリウィンドウで観ると4バイトで値が入ってます。 ウォッチで名前に「*(unsigned int *)host->h_addr_list[0]」としても確認できます。 >回線がバグっていたようで今表示されました。 >#5の補足にコードを記述してありますが、ブロッキングはされていないようです。 connect()がタイムアウトしたのでしょう。 http://msdn.microsoft.com/en-us/library/windows/desktop/ms737625%28v=vs.85%29.aspx WSAGetLastError()でエラーコードが確認できるはずです。 んで…… そのプログラムを実行している環境(LAN)のグローバルIPアドレスはなんです? ddo.jpはDDNSのようですが……。 LAN内部からブロードバンドルータのWAN側IPアドレスへの接続要求を通したいのでしたらそれ相応の製品が必要ですが、そこらヘンはクリアされているんですかね? NATループバックとかヘアピンNATとか…。 # Aterm WR8300Nでは…connect()がSOCKET_ERRORを返却、WSAGetLastError()が10061を返却。 # エラールックアップで10061を検索すると「対象のコンピューターによって拒否されたため、接続できませんでした。」でした。 # ポート番号は外向けに開けてある非標準ポート番号(外部からのssh接続のために開けてある)のもの。

Null0lluN
質問者

補足

一応、ポートを解放しているのでネットまでいったん出してからPCに戻すという方法は可能です(ホスト名を使わないでアドレスを直接inet_addr()で入れるとちゃんと通信できる)

回答No.5

ほかに考えられるのは、gethostbynameがエラー(NULL)を返したにも関わらず、エラーメッセージの表示等することなく、何事もなかったかのように処理を進めようとしているなど。

Null0lluN
質問者

補足

#3の補足にもある通り、NULLは帰ってきてないようです。 ただ、h_addr_listの値が 0x00625284 "|esonline.ddo.jp" であるようなので、どちらにしろconnectではストップしてるでしょうね しかし、解せないのはconnect前のprintfが表示されないこと・・・・・ もちろん、正しいgethostbynameの使い方も知りたいですが。

回答No.4

それは単に、DNSサーバからすぐに応答がなく、タイムアウトまで待たされているからでしょう。gethostbynameでブロッキングされて、制御が返ってきていないだけです。

Null0lluN
質問者

お礼

ごめんなさい。自分の勘違いでした。#3の補足で合ってます

Null0lluN
質問者

補足

回線がバグっていたようで今表示されました。 #5の補足にコードを記述してありますが、ブロッキングはされていないようです。

  • wormhole
  • ベストアンサー率28% (1626/5665)
回答No.3

>しかし、例えば画像を描画しようとしても何も起こらないのです。(gethostbynameをコメントアウトすれば描画される) gethostbynameを使ってるのが問題だと思うのでしたら、せめてその部分のコードくらい書きませんか。 今ある情報だけだと「gethostbynameを使って何か変なことしてるんでしょ」くらいしかいえません。

Null0lluN
質問者

お礼

ああ、書き忘れがありました。 上の補足だけだと、もしかしたらIPアドレスがちゃんと格納されておらず(つまりconnect失敗)の可能性もあるため、 connectの前に printf( "test" ); としましたが、表示されませんでした

Null0lluN
質問者

補足

エラーが起こる最低限のプログラムはこうです (この場合だとデータの送受信が出来ない) http://www.geekpage.jp/programming/winsock/tcp.php このページのクライアントとサーバープログラムをそれぞれコピペし、 クライアントプログラムのIPアドレスの部分を struct hostent *host; ----host = gethostbyname("esonline.ddo.jp"); if( host!=NULL ) { ----server.sin_addr.S_un.S_addr = *(unsigned int *)host->h_addr_list[0]; } としています。 これを使うとデータの送受信が一切できません。これをコメントアウトして server.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); だとちゃんと成功します なお、if文の中には入っているようです。

  • Wr5
  • ベストアンサー率53% (2173/4061)
回答No.2

気にするようなものでもないんですけどね。 >gethostbynameをコメントアウトするとそのようなエラーは出ません。 関連するDLLを読み込まないから…でしょう。 gethostbynameをコメントアウトしたところで、別のDLLを読み込んだ際に似たような表示はあるハズですが。 'C:\Windows\SysWOW64\ntdll.dll' を読み込みました。Cannot find or open the PDB file 'C:\Windows\SysWOW64\kernel32.dll' を読み込みました。Cannot find or open the PDB file 'C:\Windows\SysWOW64\KernelBase.dll' を読み込みました。Cannot find or open the PDB file 'C:\Windows\SysWOW64\msvcp100d.dll' を読み込みました。シンボルが読み込まれました。 'C:\Windows\SysWOW64\msvcr100d.dll' を読み込みました。シンボルが読み込まれました。 とか。 # うざったいので「モジュールの読み込みメッセージ」「モジュールのアンロード メッセージ」は表示しないようにしていますね。 >例えば画像を描画しようとしても何も起こらないのです。(gethostbynameをコメントアウトすれば描画される) なんらかのバグが表面化しているだけでは? コード掲示されているわけでもないので、その不具合がどちらにあるものなのかは不明ですが。

Null0lluN
質問者

お礼

回線がバグっていたようで#5の補足です

Null0lluN
質問者

補足

申し訳ありません コードは#3の補足に挙げます

回答No.1

その出力メッセージはエラーではありません。実際に、何も問題なくプログラムを実行することができているはずです。 デバッガは実行時に.exeや.dllがロードされるとき、そのDLLのデバッグシンボルが定義された.pdbファイルを探そうとします。これは、自分で作成した.exeや.dllだけでなく、WindowsのシステムDLLに関しても同じように動きます。 ただし、デフォルトの状態ではデバッグ時にシステムDLLの.pdbをマイクロソフトのシンボルサーバから自動的にダウンロードしてくるようには設定されておらず、デバッガ上で実行したときはシステムDLLを読み込む際にそのメッセージが出力されてしまいます。 デバッグオプションの設定でマイクロソフトのシンボルサーバからシンボルを読み込むようにすれば、(シンボルサーバがシンボルを提供するDLLに限っては)そのメッセージが出力されないようになりますが、若干起動が遅くなったりなどする可能性があるので、特に必要なければそのままで問題ないです。

Null0lluN
質問者

補足

しかし、例えば画像を描画しようとしても何も起こらないのです。(gethostbynameをコメントアウトすれば描画される)

関連するQ&A

専門家に質問してみよう