2012-01-25 36 views
3

我們正在開發要安裝在客戶端系統上的Windows服務。此應用程序定期調用我們服務器上的SOAP Web服務。我們希望在客戶端系統的本地IP地址每次訪問我們的服務以進行故障排除時將其包含在SOAP請求中。通過在這裏的其他帖子看,我發現下面的代碼來獲得IP地址的列表的系統接口:被包含在Windows服務獲取用於在Windows服務中進行Web服務調用的接口的本地IP地址

IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName()); 

此代碼。是否有一種簡單的方法可以確定將此陣列中的哪個IP分配給Web服務呼叫路由到的接口?

+0

不是真的 - 路由發生在請求建立後。最好你可以做的是服務器端捕獲請求來自的IP,但取決於路由/ NAT,你可能看不到發起者的IP。 – Joe

+0

@Joe,謝謝。因此,如果我使用HttpWebRequest對象來訪問服務,那麼沒有辦法獲得發送請求的接口的本地IP地址?本地IP確實是我們想要的。這聽起來像一個可行的替代方案 - 我嘗試使用Socket類連接到端點,然後獲取套接字的LocalEndPoint。通過這樣做我會冒險返回錯誤的IP嗎?我認爲套接字連接和服務請求可能不一定通過相同的接口進行路由。 – Poosh

回答

1

如果您正在使用WCF 3.5或更高版本,你可以直接通過如在本blog

+0

謝謝。我應該提到客戶端沒有打到WCF服務。我們不希望在他們正在訪問的服務中捕獲IP地址,因爲我們要確保我們記錄請求源自的系統的本地IP。有沒有辦法在客戶端運行的長時間運行的Windows服務中確定這一點? – Poosh

0

的代碼,你可以在你的Windows服務運行下面的代碼使用郵件屬性獲得該服務的客戶端的IP地址獲取盒子上任何接口的IP。

/// <summary> 
/// Returns the IP Address of the given interface 
/// </summary> 
/// <param name="InterfaceName">Name of the interface</param> 
/// <param name="AddressFamily">Address family to search for</param> 
/// <returns>IPAddress of assinged IP address</returns> 
public IPAddress GetIPAddress(string InterfaceName, System.Net.Sockets.AddressFamily AddressFamily) 
{ 
    System.Net.NetworkInformation.NetworkInterface Interface = GetInterface(InterfaceName); 
    if (Interface != null) 
    { 
     foreach (System.Net.NetworkInformation.UnicastIPAddressInformation IP in Interface.GetIPProperties().UnicastAddresses) 
     { 
      //Match address family 
      if(IP.Address.AddressFamily != AddressFamily) 
       continue; 

      //Check for IPv6 conditions since we can easily have multiple IPs 
      if(IP.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6 && (IP.Address.IsIPv6LinkLocal || IP.AddressPreferredLifetime != uint.MaxValue || IP.AddressValidLifetime != uint.MaxValue)) 
       continue; 

      //We've found the IP 
      return IP.Address; 
     } 
    } 

    return null; 
} 

/// <summary> 
/// Returns the Network Interface for the given windows name 
/// </summary> 
/// <param name="InterfaceName">Interface name to get (ie Local Area Connection)</param> 
/// <returns>Network Interface, or null if not found</returns> 
System.Net.NetworkInformation.NetworkInterface GetInterface(string InterfaceName) 
{ 
    if (InterfaceName == null || InterfaceName.Length == 0) 
     return null; 

    foreach (System.Net.NetworkInformation.NetworkInterface Interface in NetworkInterfaceArray) 
    { 
     if (Interface.Name == InterfaceName) 
      return Interface; 
    } 

    return null; 
} 
+0

謝謝。是否有任何額外的邏輯可以添加到確定哪個接口正在用於訪問Web服務?我們希望獲得發起請求的單個本地IP。 – Poosh

0

返回包含在那裏的,只要適配器並沒有loopback接口的計算機上運行的IP列表。

public static List<string> DisplayDnsAddresses() 
{ 
    var addresses = NetworkInterface.GetAllNetworkInterfaces() 
     .Where(a => a.OperationalStatus == OperationalStatus.Up 
        && a.NetworkInterfaceType != NetworkInterfaceType.Loopback) 
     .Select(a => a.GetIPProperties()) 
     .SelectMany(ipp => ipp.UnicastAddresses 
      .Select(x => x.Address.ToString())); 

    return addresses.ToList(); 
} 

這可能需要細化一下。我不確定如何確定Web服務將使用哪個接口,但是如果您知道必須用於訪問網絡的網關,那麼也許可以將其關閉。

+0

感謝您的建議,我會仔細研究一下,看看這是確定Web服務使用哪種界面的可行方法。 – Poosh