私のアプリケーションは C# .net Framework 3.5 です。
アプリケーションの主な機能は次のとおりです。
- ユーザーにネットワーク インターフェイス カード (NIC) を選択させる
- ユーザーが選択した NIC に IP アドレス (およびサブネット マスク) を割り当てます - Win32_NetworkAdapterConfigurationクラスの WMI - EnableStatic メソッドを使用します。
- 指定された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アドレスだけを削除する方法はありますか?
質問が十分に明確であることを願っています。お時間をいただきありがとうございます。