我的应用程序是 C# .net Framework 3.5。
该应用程序的主要功能是:
- 让用户选择网络接口卡(NIC)
- 为用户选择的 NIC 分配一个 IP 地址(和子网掩码) - 我使用 WMI - Win32_NetworkAdapterConfiguration类的 EnableStatic 方法。
- 通过一个进程启动一个第 3 方 C++ exe 组件,它的行为就像一个服务器,它将监听给定的 IP 地址 - 绑定功能由服务器实现,所以在进程启动时我只是传递正确的 IP 地址和它开始听那个。
操作 2 和 3 可以无限次重复,因此可以为同一个 NIC 分配多个 IP 地址并拥有多个服务器,每个服务器都侦听自己的 IP 地址。
要将 IP 地址分配给给定的 NIC,我使用 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;
}
}
现在,当用户想要杀死一个活动服务器时,我的问题就出现了。在服务器关闭时,我必须从 NIC 中删除服务器正在侦听的 IP 地址。
杀死进程这不是问题,但是当我调用我的 ChangeNetworkInterfaceIPs 以使用新的 IP 地址列表(即:没有 IP 地址的旧列表)更新分配给 NIC 的 IP(删除不再使用的服务器)时被杀死的服务器)发生了一些非常奇怪的事情:随机一些其他正在运行的服务器得到一个 SOCKET_ERROR 并且它们的连接已关闭。
知道发生了什么吗?为什么当我从 NIC中删除未使用的 IP 地址时,正在运行的服务器会随机获取 SOCKET_ERRORs?此外,我知道可能设置一个完整的 IP 地址列表只是为了删除一个它并不是一个最佳实践:有没有办法只删除一个给定的 IP 地址?
我希望这个问题足够清楚。感谢您的时间。