【问题标题】:Host Name is sometimes empty主机名有时为空
【发布时间】:2016-09-30 01:28:34
【问题描述】:

在我的一个应用程序 (ASP.NET/VB.NET) 中,我需要读取客户端计算机名称。基于客户端机器,我们触发一个销售点支付设备来接受付款。在这些系统中的每一个上,我们都安装了一个独立的软件,它使用 HTTP 请求与银行进行通信。我正在使用以下 .NET 代码来读取客户端计算机名称。

Dim name As String = String.Empty
Dim hostEntry = Dns.GetHostEntry(HttpContext.Current.Request.UserHostAddress)
If hostEntry.HostName.Contains(".") Then
    name = hostEntry.HostName.Substring(0, hostEntry.HostName.IndexOf("."))
Else
    name = hostEntry.HostName.Trim
End If

在开发环境中,我们所有的系统都在一个域(“xyz.com”)中,我们没有任何问题。在客户位置,他们没有域名设置。我的上述逻辑在客户端环境中的某些系统中运行良好,并且能够进行支付,但在大多数系统中,我们的逻辑失败并且无法读取主机名。任何帮助将不胜感激。

【问题讨论】:

    标签: asp.net .net vb.net


    【解决方案1】:

    您的问题没有回答您的问题所需的细节。有很多关于这两种环境的问题需要回答才能给出正确的答案。由于我无法提问,所以我会做出一些假设,这些假设可能适用于这篇文章的未来读者并能够帮助他们。

    我会问一个问题,但我的个人资料因某种未知原因被分叉,而且我没有提出问题所需的声誉。话虽如此,我将列出我可以立即识别的问题并提出解决方案的建议,希望能引导您找到解决方案。

    所以……

    1) 您声明您需要读取客户端计算机名称。但是,如果您的应用程序未在内部 LAN(也称为 Intranet)上运行,则您无法读取客户端计算机名称期间。所以这可能是你的第一个问题。

    2) 结合点 1 并假设您正在从客户端的 UserHostAddress 读取 IP 地址以查找 DNS 主机名,并且当主机查找成功时,您将获取名称的第一部分直到第一个“ 。”可以安全地假设这是一个在您的开发环境和客户端环境中都在 LAN 上运行的 Intranet 应用程序。有了这个假设并给出了所有机器都被赋予 xyz.com 域的声明,可以假设您的开发环境中的 DNS 正在通过 Active Directory (AD) 进行动态更新。在这种情况下,每当开发网络上的客户端机器请求 IP 地址时,可能是通过 AD,与 AD 集成的 DHCP 服务器会发布新的 IP 地址。当它这样做并且 DHCP 提议被客户端确认并接受时,AD 更新 DNS(在 Windows 网络上也集成了 AD),方法是添加一个主机条目,其中客户端计算机的计算机名称指向 IP 地址。此外,根据配置,可以将 DNS 指针添加到 AD 的 DNS 中,从而允许 IP 地址查找解析到记录(在这种情况下是客户端的机器名称)。因此,使用您的开发环境(可能在 Windows Active Directory 域上运行)一切正常。此外,默认情况下,顶级域名 (XYZ.COM) 在来自客户端的初始 DNS 请求中附加到客户端计算机名称。

    3) 您的客户没有运行域,这会留下更多问题。他们在运行窗户吗?如果他们正在运行 Windows,它是否作为非广告环境,例如工作组。第一个假设是它们没有集成 AD,否则你很可能不会遇到这个问题,尽管我可以想到一些罕见的情况。但是,相关问题很可能是它们正在运行什么 DNS 服务器以及它们正在运行什么 DHCP 服务器?您的应用程序正在尝试在其网络上使用客户端 IP 地址,并且基于其 IP 的主机名查找失败,因此它告诉我在他们的环境中出于某种原因您无法从 IP 地址获取主机名客户。请注意,如果他们可以在 AD 上并完全正确配置,他们的 DNS 服务器只是不堪重负,在 2 秒内没有响应,导致名称查找失败,但这是速率情况。有了更多信息,我可以提供更多帮助。

    3) 假设 2 中它们不在 AD 上,您是否有能力在您的应用程序运行的计算机上手动编码主机名?例如,假设 yourapp.exe 运行 client-server-01 并且客户端连接到它。然后在 client-server-01 上,您可以在主机文件中为您希望连接的客户端网络上的每台 PC 添加静态 DNS 条目。另一方面,如果您的应用程序在客户端 PC 上本地运行,您可以将机器名称作为 Web 请求中的标头传递,然后从服务器上的 Request.Headers 变量中读取它。

    4) 再次假设客户端是基于 Web 的,并且客户端环境中的应用程序托管在服务器上...服务器是否位于客户端环境之外的 DMZ 上?如果是这样,则客户端环境可能会根据最佳实践进行配置,即托管您的 Web 应用程序的服务器位于 DMZ 中,并且对该框的 DNS 请求被转发到客户端的 ISP,而不是返回到具有 DNS 服务器的网络中将内部 IP 解析为客户端计算机名称。如果是这种情况,您需要将客户端计算机名称作为变量从客户端发送,或将本地 IP 编码到服务器主机文件中的主机名(假设内部网络不在 NAT 之后并公开真实客户端计算机的 IP)或请求 DMZ 的服务器可以访问内部 DNS 并相应地配置访问。

    ....

    这个清单确实不胜枚举,但我认为我强调了 99% 的情况的问题,并提供了各种解决方案的答案。

    【讨论】:

    • Alexander:感谢您抽出宝贵的时间回答我的问题。是的,他们没有广告设置。但是,他们为每个 POS 系统分配了一个共同的工作组。我的问题是它在某些客户端系统中是如何工作的?
    • 应用程序在内部 LAN 中运行。在WINDOWS操作系统中使用的应用程序
    • 这里是场景,我的 xyz.com 网站在 client-server-01,client-02...等上浏览。应用程序应读取 client-01 并将该名称发送到 IIS 服务器,该服务器将执行一些操作,然后进行 HTTP POST 调用以将数据发送到安装在 POS 系统上的软件。它将在内部触发连接在客户端计算机上的支付设备(client-01)。
    【解决方案2】:

    您可以尝试从X-Forwarded-For header 中获取

    X-Forwarded-For (XFF) HTTP 标头字段是一种常用方法 识别连接到 Web 的客户端的原始 IP 地址 服务器通过 HTTP 代理或负载平衡器。

    这是 X-Forwarded-For 应该返回的:

    X-Forwarded-For:客户端、proxy1、proxy2

    这里有一些示例代码:

    string ip = Request.ServerVariables["HTTP_X_FORWARDED_FOR"] ;
    if (!string.IsNullOrEmpty(ip))
    {
       string[] ipRange = ip.Split(',');
       ip = ipRange[0];
    }
    else
    {
       ip = Request.ServerVariables["REMOTE_ADDR"];
    }
    

    【讨论】:

      【解决方案3】:

      客户端计算机上的防火墙设置存在问题。由于我们的 .NET 代码失败。在为来自 xyz.com 的所有传入请求添加例外之后。我的代码工作没有任何问题。

      感谢@Alexander Higgins、@halfer 的帮助。

      【讨论】:

        猜你喜欢
        • 2020-09-19
        • 2014-06-18
        • 1970-01-01
        • 2014-06-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-05
        • 1970-01-01
        相关资源
        最近更新 更多