简体   繁体   English

确定进程正在使用的网络适配器

[英]Determine which network adapter a process is using

I've seen several similar questions on Google, but nothing exactly matches what I'm trying to do. 我在谷歌上看过几个类似的问题,但没有什么能与我想做的完全匹配。 I'm making a lag-reducing program (for a game) that basically lowers the user's MTU when a certain process is open, and restores it when the process is closed. 我正在制作一个延迟减少程序(用于游戏),当某个进程打开时,它基本上会降低用户的MTU,并在进程关闭时恢复它。 However, MTU is a network-adapter specific setting, and some users have multiple connected network adapters. 但是,MTU是特定于网络适配器的设置,并且一些用户具有多个连接的网络适配器。 To this end, I thought it'd be nice to have the program also detect which adapter is being used by the game, and only change the MTU on that adapter. 为此,我认为让程序检测到游戏正在使用哪个适配器并且只更改该适配器上的MTU是很好的。

The game will only use one adapter at a time. 游戏一次只能使用一个适配器。

I can't hardcode in end-server-IP addresses because they change fairly frequently. 我无法在终端服务器IP地址中进行硬编码,因为它们会相当频繁地更改。 It seems to be there must be a way to determine which adapter the other process is using without knowing the end IP address, but I can't seem to find it. 似乎必须有一种方法来确定其他进程使用哪个适配器而不知道最终IP地址,但我似乎无法找到它。

EDIT : Thanks to Cicada and Remco, I've solved the problem. 编辑 :感谢Cicada和Remco,我已经解决了这个问题。

I used the ManagedIPHelper class that Remco linked to ( ManagedIpHelper ) and Cicada's comments led me to this article ( Identifying active network interface ) 我使用Remco链接到的ManagedIPHelper类( ManagedIpHelper )和Cicada的评论引导我阅读本文( 识别活动网络接口

Combining those with some (Nasty, horribly unoptimized) LINQ, I got this code snippet, which takes the process name and returns the Network Interface it's using, or null if it can't find one. 将这些与一些(讨厌的,可怕的未经优化的)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;
    }

Testing confirms this works perfectly ! 测试证实这完美无缺 Many thanks, guys! 非常感谢,伙计们!

Side notes to anyone using this snippet: 对使用此代码段的任何人的旁注:

  • You'll need the ManagedIpHelper classes. 您将需要ManagedIpHelper类。
  • Your app may need to request elevation, depending on the situation. 您的应用可能需要请求提升,具体取决于具体情况。
  • Multiple running processes (think Chrome) will return an undefined result. 多个运行进程(想想Chrome)将返回未定义的结果。 If you're going to use this code with a multpile-process-candiate situation, I highly recommend you change using (Process p = candidates[0]) to a more specific filter, ie based on PID. 如果您要将此代码用于具有多个流程的候选情况,我强烈建议您使用(处理p =候选[0])更改为更具体的过滤器,即基于PID。
  • You may also want to impliment new exception types, so you can, for example, catch "No routing info" more cleanly, the reason being that this error is often fixed by simply waiting a bit (to let the target process open a connection) and then retrying. 您可能还想要实现新的异常类型,因此您可以更清楚地捕获“无路由信息”,原因是通常只需稍等一下(让目标进程打开连接)就可以修复此错误然后重试。

in addition to Cicada, this must help you: 除了蝉,这必须帮助你:

It is a C# wrapper around some c/c++ code, which gets you the list of all open connections with associated PID ( Process Id ). 它是一些围绕某些c / c ++代码的C#包装器,它会为您提供所有具有关联PID(进程ID)的打开连接的列表。

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

I do believe this is the only way to go, determine the process(id) based on executable path/name and try to find the current connection of that process. 我相信这是唯一的方法,根据可执行路径/名称确定进程(id)并尝试查找该进程的当前连接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM