none
VB6 複数NICあるうちから任意のNICからの送信方法 RRS feed

  • 質問

  •   VB6の質問です。

    1つのPCに複数のNICがあり、それぞれのNICは違うレイアのアドレスを持っているとします。
    それぞれに対応するホストがあるとします。
    それらは、LANでつながっています。
    以下のような感じです。

    NIC_A(192.168.81.100)
    NIC_B(192,168.80.100)

    HOST_A(192.168.81.1)
    HOST_B(192.168.80.1)

    winsockを使うと、任意のアドレスから出力できるらしいのですが、
    実現方法がわかりません。

    下記のソースを実行すると、エラー40020「現在の状態では不正な処理です」と表示され、connectができません。

          Private Sub Form_Load()
             Winsock1.LocalPort = 0
             Winsock1.Bind 21, "192.168.81,100"
             Winsock1.Connect "192.168.81.1", 21 <-ここでエラーとなる
          End Sub

    任意のNICからの送信方法をご教授ください。
    よろしくお願いします。
    2009年2月12日 5:50

回答

  • 回答ではありません。

    りん太 さん の発言:

    下記のソースを実行すると、エラー40020「現在の状態では不正な処理です」と表示され、connectができません。

          Private Sub Form_Load()
             Winsock1.LocalPort = 0
             Winsock1.Bind 21, "192.168.81,100"
             Winsock1.Connect "192.168.81.1", 21 <-ここでエラーとなる
          End Sub

    BindはListenするため、つまり、待ち受けポートとして設定するためのものであり、どのNICを使うかを指定するためのものではありません。
    サーバーのように待ち受け状態に入ろうとしている状態で、他のPCにConnect(接続)しようとしているので、エラーになっているのでは?


    複数のNICを使い分けるにはルーティングテーブルとかそういったレベルの話になるのかなぁ?
    (Raw Socketでできるのかどうかは知らない)

    参考になった返信には「回答としてマーク」のボタンを利用して、回答に設定しましょう(複数に指定できます)。
    • 回答としてマーク sk7474 2009年3月11日 7:40
    2009年2月12日 14:56
    モデレータ
  • そのネットワーク構成であるなら、connectだけすれれば、
    Windowsが適切なNICを選択するはずですが。
    ルーティングによる送信元決定だけでは何か不十分なのでしょうか?

    jzkey
    • 回答としてマーク sk7474 2009年3月11日 7:39
    2009年2月15日 10:15
  • りん太さんからの返信がないので、jzkeyさんの回答の補足をしたいと思います。

    > 1つのPCに複数のNICがあり、それぞれのNICは違うレイアのアドレスを持っているとします。
    > それぞれに対応するホストがあるとします。

     一つのPCにNICを複数差した時点で、それはルーターと同じ扱いとなり、そのためにルーティングテーブルを設定が必要となります。
     そのためどのNICを使用するか、というのはプログラムで考慮する必要はなく、設定されているルーティングテーブルに従って(ルーティングテーブルが正しければ)適切なNICが使用されます。

     今回の場合、ルーティングテーブルが正しく設定されていないために通信できていないものと思われます。
    (デフォルトゲートウェイを設定する場合、NICが複数差さっているため、というような警告が表示されませんでしたか?)

     なお、ルーティングテーブルを表示/設定するためのコマンドとしてROUTEというコマンドがあります。
     コマンドプロンプトで「ROUTE /?」もしくは「ROUTE」だけ入力するとヘルプメッセージが表示されますので、細かい使用方法についてはそれを、もしくはルーティングに関して説明しているサイトを参考にしてください。

     簡単に説明しますと、現在設定されているルーティングテーブルを表示するには、「ROUTE PRINT」、ルーティングテーブルを追加するには「ROUTE ADD」を使います。

     ROUTE PRINTした結果を貼り付ければ、どのような設定をすれば良いか回答があると思います。

    # といいつつ、自分はルーター専用機でのルーティングはともかくPCでのルーティングテーブルの設定って苦手なんだよなぁ。
    • 回答としてマーク sk7474 2009年3月11日 7:39
    2009年2月22日 15:15
  • 当てずっぽうで、Winsock1.LocalPort = 0を消したらどうなりますか? この行もBind相当のことを行うので、2回できなくてエラーになっているのかも。
    socketプログラミングとしてconnect()前にbind()するのは構いません。ただしWinsockやMSWINSCK.OCXがそれをサポートしているか、まではわかりません。

    試しにVB6はインストールしてみましたがさすがにmulti home環境まで構築する気にはなれませんでした。

    それとは別に、毎回エラーになるのでしょうか? エラーの内容は同じなのでしょうか。
    前回のセッションが残っていて、それが原因でサーバ側もしくはクライアント側が混乱している可能性もあります。
    Bindの引数を毎回異なるポート番号を使用すればこれに関しては回避できると思いますが。
    (毎回ポート番号を変化させる行為がWinsock1.LocalPort = 0です。)

    既におわかりかと思いますが、直接NICを指定しての操作はできず、NICに割り振られているIPアドレスを指定して、となります。
    ですが、ルーティングテーブルというものがあり、HOST_A(192.168.81.1)に接続しようとしたときには自動的にNIC_A(192.168.81.100)が使われます。その逆も。
    これがNIC_Bを使ってHOST_Aへの接続といった変則的なの場合にコーディングされているようなlocal address指定が必要になります。

    • 回答としてマーク sk7474 2009年3月11日 7:39
    2009年2月23日 16:22

すべての返信

  • 回答ではありません。

    りん太 さん の発言:

    下記のソースを実行すると、エラー40020「現在の状態では不正な処理です」と表示され、connectができません。

          Private Sub Form_Load()
             Winsock1.LocalPort = 0
             Winsock1.Bind 21, "192.168.81,100"
             Winsock1.Connect "192.168.81.1", 21 <-ここでエラーとなる
          End Sub

    BindはListenするため、つまり、待ち受けポートとして設定するためのものであり、どのNICを使うかを指定するためのものではありません。
    サーバーのように待ち受け状態に入ろうとしている状態で、他のPCにConnect(接続)しようとしているので、エラーになっているのでは?


    複数のNICを使い分けるにはルーティングテーブルとかそういったレベルの話になるのかなぁ?
    (Raw Socketでできるのかどうかは知らない)

    参考になった返信には「回答としてマーク」のボタンを利用して、回答に設定しましょう(複数に指定できます)。
    • 回答としてマーク sk7474 2009年3月11日 7:40
    2009年2月12日 14:56
    モデレータ
  • Azulean様
    返信が遅くなって申し訳ありません。
    VBでは、任意のNICからの送信はできないと考えて良いのでしょうか?

    ルーティングテーブルについて調べてみます。
    ありがとうございました。
    2009年2月13日 13:59
  • りん太 さん の発言:

    VBでは、任意のNICからの送信はできないと考えて良いのでしょうか?

    申し訳ありませんが、それについては言明できません。
    理由としては、「Windowsの仕組みとしてできるかどうか」を私が分かっていません。(確たる裏付けを取れない)

    Windowsが何らかの手段を提供しているのであれば、VBからも実現の可能性はあります。
    逆に、手段が提供されていない場合は、VBであれ、何であれ実現不可能です。
    参考になった返信には「回答としてマーク」のボタンを利用して、回答に設定しましょう(未解決の場合を除く)。
    2009年2月13日 14:55
    モデレータ
  •  Azulean様

    たびたびのご回答、ありがとうございます。
    難しいですが、まずは「できる、できない」を調べてみようと思います。
    ありがとうございました。
    2009年2月15日 7:06
  • そのネットワーク構成であるなら、connectだけすれれば、
    Windowsが適切なNICを選択するはずですが。
    ルーティングによる送信元決定だけでは何か不十分なのでしょうか?

    jzkey
    • 回答としてマーク sk7474 2009年3月11日 7:39
    2009年2月15日 10:15
  • りん太さんからの返信がないので、jzkeyさんの回答の補足をしたいと思います。

    > 1つのPCに複数のNICがあり、それぞれのNICは違うレイアのアドレスを持っているとします。
    > それぞれに対応するホストがあるとします。

     一つのPCにNICを複数差した時点で、それはルーターと同じ扱いとなり、そのためにルーティングテーブルを設定が必要となります。
     そのためどのNICを使用するか、というのはプログラムで考慮する必要はなく、設定されているルーティングテーブルに従って(ルーティングテーブルが正しければ)適切なNICが使用されます。

     今回の場合、ルーティングテーブルが正しく設定されていないために通信できていないものと思われます。
    (デフォルトゲートウェイを設定する場合、NICが複数差さっているため、というような警告が表示されませんでしたか?)

     なお、ルーティングテーブルを表示/設定するためのコマンドとしてROUTEというコマンドがあります。
     コマンドプロンプトで「ROUTE /?」もしくは「ROUTE」だけ入力するとヘルプメッセージが表示されますので、細かい使用方法についてはそれを、もしくはルーティングに関して説明しているサイトを参考にしてください。

     簡単に説明しますと、現在設定されているルーティングテーブルを表示するには、「ROUTE PRINT」、ルーティングテーブルを追加するには「ROUTE ADD」を使います。

     ROUTE PRINTした結果を貼り付ければ、どのような設定をすれば良いか回答があると思います。

    # といいつつ、自分はルーター専用機でのルーティングはともかくPCでのルーティングテーブルの設定って苦手なんだよなぁ。
    • 回答としてマーク sk7474 2009年3月11日 7:39
    2009年2月22日 15:15
  • 当てずっぽうで、Winsock1.LocalPort = 0を消したらどうなりますか? この行もBind相当のことを行うので、2回できなくてエラーになっているのかも。
    socketプログラミングとしてconnect()前にbind()するのは構いません。ただしWinsockやMSWINSCK.OCXがそれをサポートしているか、まではわかりません。

    試しにVB6はインストールしてみましたがさすがにmulti home環境まで構築する気にはなれませんでした。

    それとは別に、毎回エラーになるのでしょうか? エラーの内容は同じなのでしょうか。
    前回のセッションが残っていて、それが原因でサーバ側もしくはクライアント側が混乱している可能性もあります。
    Bindの引数を毎回異なるポート番号を使用すればこれに関しては回避できると思いますが。
    (毎回ポート番号を変化させる行為がWinsock1.LocalPort = 0です。)

    既におわかりかと思いますが、直接NICを指定しての操作はできず、NICに割り振られているIPアドレスを指定して、となります。
    ですが、ルーティングテーブルというものがあり、HOST_A(192.168.81.1)に接続しようとしたときには自動的にNIC_A(192.168.81.100)が使われます。その逆も。
    これがNIC_Bを使ってHOST_Aへの接続といった変則的なの場合にコーディングされているようなlocal address指定が必要になります。

    • 回答としてマーク sk7474 2009年3月11日 7:39
    2009年2月23日 16:22
  •  佐祐理様 Cattail様 jzkey様
    回答ありがとうございます。

    ルーティングテーブルで解消できそうな問題ですので、
    これで対応してみようと思います。

    実機がないので、すぐに対応できませんが
    試した結果をご報告したいと思います。
    2009年2月24日 20:12
  • こんにちは。中川俊輔 です。

    皆様、回答ありがとうございます。

    りん太さん、フォーラムのご利用ありがとうございます。
    勝手ながら有用な情報と思われる回答へ回答マークをつけさせていただきました。

    問題は解決しましたか?よろしければぜひ結果を投稿してみてください。

    今後ともフォーラムをよろしくお願いします。
    それでは!
    マイクロソフト株式会社 フォーラム オペレータ 中川 俊輔
    2009年3月11日 8:50