0

我的应用程序是 C# .net Framework 3.5。

该应用程序的主要功能是:

  1. 让用户选择网络接口卡(NIC)
  2. 为用户选择的 NIC 分配一个 IP 地址(和子网掩码) - 我使用 WMI - Win32_NetworkAdapterConfiguration类的 EnableStatic 方法。
  3. 通过一个进程启动一个第 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 地址?

我希望这个问题足够清楚。感谢您的时间。

4

1 回答 1

0

我没有回答帖子中提出的所有问题,但发布这可能对像我这样的初学者有所帮助。

问题:有没有办法只删除给定的 IP 地址?
答:netsh在c#中将命令作为进程运行

Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "netsh";
p.StartInfo.Arguments = "netsh interface ipv4 delete address \"my NIC Name\" addr=192.168.1.1";
p.Start();
string response = p.StandardOutput.ReadToEnd();
p.Close();

注意:此命令必须以管理员身份运行。

于 2017-02-06T11:22:26.210 回答