4

我在谷歌上看到了几个类似的问题,但没有什么完全符合我想要做的。我正在制作一个减少延迟的程序(用于游戏),它基本上会在某个进程打开时降低用户的 MTU,并在进程关闭时恢复它。但是,MTU 是特定于网络适配器的设置,有些用户有多个连接的网络适配器。为此,我认为最好让程序也检测游戏正在使用哪个适配器,并且只更改该适配器上的 MTU。

游戏一次只能使用一个适配器。

我无法硬编码终端服务器 IP 地址,因为它们变化相当频繁。似乎必须有一种方法可以在不知道最终 IP 地址的情况下确定其他进程正在使用哪个适配器,但我似乎找不到它。

编辑:感谢 Cicada 和 Remco,我已经解决了这个问题。

我使用了 Remco 链接到的 ManagedIPHelper 类(ManagedIPHelper),Cicada 的评论让我看到了这篇文章(识别活动网络接口

将它们与一些(讨厌的,非常未优化的)LINQ 结合起来,我得到了这个代码片段,它采用进程名称并返回它正在使用的网络接口,如果找不到,则返回 null。

    private NetworkInterface getAdapterUsedByProcess(string pName)
    {
        Process[] candidates = Process.GetProcessesByName(pName);
        if (candidates.Length == 0)
            throw new Exception("Cannot find any running processes with the name " + pName + ".exe");

        IPAddress localAddr = null;
        using (Process p = candidates[0])
        {
            TcpTable table = ManagedIpHelper.GetExtendedTcpTable(true);
            foreach (TcpRow r in table)
                if (r.ProcessId == p.Id)
                {
                    localAddr = r.LocalEndPoint.Address;
                    break;
                }
        }

        if (localAddr == null)
            throw new Exception("No routing information for " + pName + ".exe found.");

        foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
        {
            IPInterfaceProperties ipProps = nic.GetIPProperties();
            if (ipProps.UnicastAddresses.Any(new Func<UnicastIPAddressInformation, bool>((u) => { return u.Address.ToString() == localAddr.ToString(); })))
                return nic;
        }
        return null;
    }

测试证实这非常有效!非常感谢,伙计们!

使用此代码段的任何人的旁注:

  • 您将需要 ManagedIpHelper 类。
  • 根据具体情况,您的应用可能需要请求提升。
  • 多个正在运行的进程(想想 Chrome)将返回未定义的结果。如果您打算在多进程候选情况下使用此代码,我强烈建议您将 使用 (Process p = Candidates[0])更改为更具体的过滤器,即基于 PID。
  • 您可能还想隐含新的异常类型,例如,您可以更干净地捕获“无路由信息”,原因是通常只需稍等片刻即可修复此错误(让目标进程打开连接)然后重试。
4

1 回答 1

2

除了蝉,这必须帮助你:

它是一些 c/c++ 代码的 C# 包装器,它可以为您提供所有打开连接的列表以及相关的 PID ( Process Id )。

http://www.timvw.be/2007/09/09/build-your-own-netstatexe-with-c/

我确实相信这是唯一的方法,根据可执行路径/名称确定进程(id)并尝试找到该进程的当前连接。

于 2012-05-28T23:39:09.833 回答