0

私のアプリケーションは C# .net Framework 3.5 です。

アプリケーションの主な機能は次のとおりです。

  1. ユーザーにネットワーク インターフェイス カード (NIC) を選択させる
  2. ユーザーが選択した NIC に IP アドレス (およびサブネット マスク) を割り当てます - Win32_NetworkAdapterConfigurationクラスの WMI - EnableStatic メソッドを使用します。
  3. 指定されたIPアドレスをリッスンするサーバーのように動作するサードパーティのC ++ exeコンポーネントのプロセスを開始します-バインディング機能はサーバーによって実装されるため、プロセスの起動時に適切なIPアドレスを渡すだけで、それを聞き始めます。

操作 2 と 3 は何度でも繰り返すことができるため、まったく同じ NIC に複数の IP アドレスを割り当て、複数のサーバーを用意して、それぞれが独自の IP アドレスをリッスンすることができます。

特定の NIC に IP アドレスを割り当てるには、WMI、特に次のコードを使用します。ここで、adapterGUID はユーザーが選択した NIC の GUID であり、newSettings は IP とサブネット マスクのリストを保持するクラスです。

public static bool ChangeNetworkInterfaceIPs(string adapterGUID, IpSettings newSettings)
    {
        try
        {
            if (String.IsNullOrEmpty(adapterGUID))
                    throw new ArgumentException("adapterGUID");

                ManagementBaseObject inPar = null;

                ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
                ManagementObjectCollection moc = mc.GetInstances();
                ManagementObject moTarget = null;

                //Look for the correct network interface
                foreach (ManagementObject mo in moc)
                {
                    //find the target management object
                    if ((string) mo["SettingID"] == adapterGUID)
                    {
                        moTarget = mo;
                        break;
                    }
                }
                if (moTarget == null)
                {
                    mc = null;
                    return false;
                }

                //we found the correct NIC. Save the current gateways, dns and wins
                object winsSecondary = moTarget.GetPropertyValue("WINSSecondaryServer");
                object gateways = moTarget.GetPropertyValue("DefaultIPGateway");
                object dnsDomain = moTarget.GetPropertyValue("DNSDomain");
                object dnsServers = moTarget.GetPropertyValue("DNSServerSearchOrder");
                object winsPrimary = moTarget.GetPropertyValue("WINSPrimaryServer");

                if (newSettings.DHCP)
                {
                    inPar = moTarget.GetMethodParameters("EnableDHCP");
                    moTarget.InvokeMethod("EnableDHCP", inPar, null);
                }
                else
                {
                    inPar = moTarget.GetMethodParameters("EnableStatic");
                    inPar["IPAddress"] = newSettings.Ips;
                    inPar["SubnetMask"] = newSettings.Netmasks;
                    moTarget.InvokeMethod("EnableStatic", inPar, null);
                }

                //restore the gateways, dns and wins
                if (gateways != null && !newSettings.DHCP)
                {
                    inPar = moTarget.GetMethodParameters("SetGateways");
                    inPar["DefaultIPGateway"] = gateways;
                    outPar = moTarget.InvokeMethod("SetGateways", inPar, null);
                }
                if (dnsDomain != null && !newSettings.DHCP)
                {
                    inPar = moTarget.GetMethodParameters("SetDNSDomain");
                    inPar["DNSDomain"] = dnsDomain;
                    outPar = moTarget.InvokeMethod("SetDNSDomain", inPar, null);
                }
                if (dnsServers != null && !newSettings.DHCP)
                {
                    //Do not restore DNS Servers in case of DHCP. Will be retrieved from DHCP Server
                    inPar = moTarget.GetMethodParameters("SetDNSServerSearchOrder");
                    inPar["DNSServerSearchOrder"] = dnsServers;
                    outPar = moTarget.InvokeMethod("SetDNSServerSearchOrder", inPar, null);
                }
                if (winsPrimary != null && !newSettings.DHCP)
                {
                    inPar = moTarget.GetMethodParameters("SetWINSServer");
                    inPar["WINSPrimaryServer"] = winsPrimary;
                    if (winsSecondary != null)
                    {
                        inPar["WINSSecondaryServer"] = winsSecondary;
                    }
                    outPar = moTarget.InvokeMethod("SetWINSServer", inPar, null);
                }

                return true;
        }
        catch
        {
            return false;
        }
    }

さて、私の問題は、ユーザーがアクティブなサーバーの1つを強制終了したい場合に発生します。サーバーの閉鎖時に、サーバーがリッスンしていた IP アドレスを NIC から削除する必要があります。

プロセスを強制終了することは問題ではありませんが、ChangeNetworkInterfaceIPs を呼び出して、新しい IP アドレスのリスト (つまり、IP アドレスのない古いリスト) を使用して、NIC に割り当てられた IP を更新する (使用されなくなったサーバーの 1 つを削除する) 場合非常に奇妙なことが起こります: 実行中の他のサーバーの一部がランダムに SOCKET_ERROR を取得し、それらの接続が閉じられます。

何が起こっているかについて何か考えはありますか?未使用のIP アドレスを NIC から削除すると、実行中のサーバーがランダムに SOCKET_ERROR を受け取るのはなぜですか? さらに、おそらくIPアドレスのリスト全体を設定して1つを削除することは、実際にはベストプラクティスではないことを知っています:特定のIPアドレスだけを削除する方法はありますか?

質問が十分に明確であることを願っています。お時間をいただきありがとうございます。

4

1 に答える 1