2010-01-08 29 views
9

Liên quan đến How to get the IP address of a WCF remote endpoint?IPv4 địa chỉ từ xa trong WCF

Tôi đang sử dụng mã này để lấy địa chỉ IP từ xa khi một phương pháp workflow được gọi:

private static string GetRemoteIP() 
{ 
    var oc = OperationContext.Current; 
    var mp = oc.IncomingMessageProperties; 
    var remp = mp[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty; 

    return remp == null ? "(unknown)" : remp.Address; 
} 

Tuy nhiên, địa chỉ tôi nhận được lại là ": : 1 ". Tôi không muốn địa chỉ IPv6, tôi muốn một địa chỉ IPv4 (127.0.0.1) - bất kỳ cách nào để buộc điều này?

Trả lời

4

Không, tôi không nghĩ vậy. Bạn về cơ bản chỉ đọc ra một tài sản được thiết lập bởi khách hàng tại thời điểm cuộc gọi. Lựa chọn duy nhất của bạn là hướng dẫn khách hàng (thông qua một số cấu hình) sử dụng IPv4 thay vì IPv6 mọi lúc (tức là tắt tất cả IPv6).

Tôi không biết về bất kỳ thiết lập WCF nào để thực thi điều đó - bạn phải đào sâu vào ngăn xếp mạng và xem có cách nào để sử dụng địa chỉ IPv4 thay vì IPv6 không.

2

Dưới đây là một cách giải quyết: (Bạn có thể lưu trữ các giá trị trong một Hashtable để tránh nhiều hoạt động DNS)

static string GetClientIP() 
    { 
     var context = OperationContext.Current; 
     var mp = context.IncomingMessageProperties; 
     var propName = RemoteEndpointMessageProperty.Name; 
     var prop = (RemoteEndpointMessageProperty) mp[propName]; 
     string remoteIP = prop.Address; 

     if(remoteIP.IndexOf(":") > -1) 
     { 
      IPAddress[] addresses = Dns.GetHostAddresses(remoteIP); 
      for (int i = 0; i < addresses.Length; i++) 
      { 
       if(addresses[i].ToString().IndexOf(".")>-1) 
        return addresses[i].ToString(); 
      } 
      return remoteIP; 
     } 
     else 
     { 
      return remoteIP; 
     } 
    } 
+0

IndexOf sẽ luôn trả về kết quả> = -1, do đó, 'if' sẽ luôn chọn nhánh khác 'else' –

+0

Không nên là câu lệnh" if "đầu tiên được đọc: if (remoteIP.IndexOf (": ")> -1)? –

3

Bạn đang nhìn thấy :: 1 bởi vì bạn đang kết nối với dịch vụ bằng cách giải quyết tên "localhost" thay vì giải quyết nó là "127.0.0.1". Các phiên bản Windows hiện đại đã bật IPv6 sẽ sử dụng IPv6 trước.

Bạn có thể vô hiệu hóa ngăn xếp IPv6, nhưng nó gần như giống như làm đà điểu và dán đầu vào cát. IPv6 đang ở đây và mọi người đang sử dụng nó trên mạng của họ, vì vậy ứng dụng của bạn nên được chuẩn bị để hỗ trợ nó.

2

Giải pháp thay thế do Murat đề xuất sẽ không hoạt động. MSDN nói - nếu bạn chuyển địa chỉ IP cho phương thức GetHostAddresses, địa chỉ này được trả về trong một mảng mà không truy vấn DNS. Để làm cho nó hoạt động, trước tiên bạn sẽ cần truy vấn tên máy chủ, sử dụng phương thức GetHostEntry. Và sau đó, sử dụng tên máy chủ lưu trữ, hãy sử dụng GetHostAddresses. Tuy nhiên, ngay cả GetHostEntry cũng có thể có danh sách các địa chỉ sẽ đủ cho bạn.

0

Bạn có thể sử dụng AddressFamily.InterNetwork == address.AddressFamilyAddressFamily.InterNetworkV6 làm thử nghiệm thay vì tìm kiếm ":" hoặc "." trong chuỗi địa chỉ.

Các vấn đề liên quan