WCF热门问题编程示例(1):WCF服务如何获得客户端IP地址信息

 今天新开了一个系列文章《WCF热门问题编程示例》:主要是针对WCF里比较有价值的问题的收集和整理,进行分析和  编程实践。最后会给出具体的示例代码。这个系列的第一篇文章:WCF热门问题编程示例(1):WCF服务如何获得客户端IP地址信息。这个问题是在MSDN中文论坛一个网友xiaochong4提出的,原文是:

    服务端通过getcallbackchannel可以取得回调的引用,对回调的调用肯定会有IP地址和端口的信息,有没有办法在服务端编程取得回调的endpoint信息.,查了好久资料没查到,大侠指教下。

原文连接地址:http://social.microsoft.com/Forums/zh-CN/wcfzhchs/thread/07ce1e3d-eddf-481c-9026-48505732d7dc

【1】问题分析:

      WCF服务能否获取客户端地址IP信息,这个问题相信很多人都遇到过。而且很多人发愁找不到解决问题的办法。我们传统的机遇Http Post/Get的网络应用和 Web Service都提供了获取客户端地址的信息的实现机制。而到了WCF,这样一个获取客户端地址的功能实现起来却是相当复杂。早期的WCF没有提供相应的支持。

      现在Orcas也就是VS2008提供了实现机制,.NET3.5一起发布。

【2】资料收集:

【2.1】stswordman2007年整理的一个文章http://www.cnblogs.com/stswordman/archive/2007/05/31/699542.html。限于当时的WCF的限制,他没有找到解决办法。而且也查找了国外的论坛,老外的建议也是不可以获取客户端地址信息,WCF当时没有提供这样的特性支持。大家有兴趣可以看看WCF英文技术论坛的帖子:
1.http://social.msdn.microsoft.com/Forums/en-US/wcf/threads

2.http://social.msdn.microsoft.com/forums/en-US/wcf/thread/3cf4aecf-4d15-44e0-8b62-a0811363091f/

   基本都是不能解决,这个受技术条件的限制,不是结论错误。现在一样做个参考。这里也对stswordman的工作表示感谢,我后续会给出正确的代码。

【2.2】后来收集的资料,Phil Henning's WebLog:http://blogs.msdn.com/phenning/archive/2007/08/08/remoteendpointmessageproperty-in-wcf-net-3-5.aspx.这个文章,提供的解决问题的方法。

    主要使用是.NET3.5里的服务端上下文的消息实例的RemoteEndpointMessageProperty属性,获取客户端地址信息。但是限制的绑定是HTTP、TCP相关的绑定协议。网络通信的底层机制来说,数据包如果经由TCP传输,IP数据包应该包含地址和端口信息,这个我们网络编程也可以理解。但是WCF获取客户端地址信息早期却没提供相应的实现。其实按照道理来说没什么难度。只是多做个数据包的解析工作,然后把地址信息包装即可。

【3】示例代码:

    这里给出服务端获取客户端IP地址信息的示例代码分析和实现过程,这里的测试主要是针对HTTP、TCP相关的协议做了4个测试。NamePipeBinding等协议不做测试了,本地协议不需要IP和端口。我们主要测试的是几个主要的协议,来验证以上的结论。

【3.1】服务端:

    主要是对RemoteEndpointMessageProperty属性的使用来获取地址、端口信息。具体代码如下:

  // 1.服务契约
    [ServiceContract(Namespace  =   " http://www.cnblogs.com/frank_xl/ " )]
    
public   interface  IWCFService
    {
        
// 操作契约
        [OperationContract]
        
string  SayHelloToUser( string  name);

    }
    
// 2.服务类,继承接口。实现服务契约定义的操作
     public   class  WCFService : IWCFService
    {

        
// 实现接口定义的方法
         public   string  SayHelloToUser( string  name)
        {
            
// 提供方法执行的上下文环境
            OperationContext context  =  OperationContext.Current;
            
// 获取传进的消息属性
            MessageProperties properties  =  context.IncomingMessageProperties;
            
// 获取消息发送的远程终结点IP和端口
            RemoteEndpointMessageProperty endpoint  =  properties[RemoteEndpointMessageProperty.Name]  as  RemoteEndpointMessageProperty;
            Console.WriteLine(
string .Format( " Hello {0},You are  from {1}:{2} " , name, endpoint.Address, endpoint.Port));
            
return   string .Format( " Hello {0},You are  from {1}:{2} " , name, endpoint.Address, endpoint.Port);


        }
    }

【3.2】宿主:使用的是控制台托管宿主方式,延续上一个些列的特色。大家很应该很容易就上手了。简单介绍一下配置过程。    这里配置了HTPP和TCP相关的4个服务终结点进行测试:

< service behaviorConfiguration = " WCFService.WCFServiceBehavior "
        name
= " WCFService.WCFService " >
        
< endpoint 
          address
= " http://localhost:8001/WCFService "  
          binding
= " wsHttpBinding "  contract = " WCFService.IWCFService " >
        
</ endpoint >
        
< endpoint 
          address
= " net.tcp://localhost:8002/WCFService "  
          binding
= " netTcpBinding "  contract = " WCFService.IWCFService " >
        
</ endpoint >
        
< endpoint
          address
= " http://localhost:8003/WCFService "
          binding
= " basicHttpBinding "  contract = " WCFService.IWCFService " >
        
</ endpoint >
        
< endpoint
          address
= " http://localhost:8004/WCFService "
          binding
= " wsDualHttpBinding "  contract = " WCFService.IWCFService " >
        
</ endpoint >
        
< endpoint address = " mex "  binding = " mexHttpBinding "  contract = " IMetadataExchange "   />
        
< host >
          
< baseAddresses >
            
< add baseAddress = " http://localhost:8001/ " />
          
</ baseAddresses >
        
</ host >
      
</ service >
    
</ services >

【3.3】客户端:启动宿主和添加服务引用的过程就详细介绍了。我们分别针对每个不同的服务终结点,实例化代理进行测试。宿主会输出信息,而且客户端打印返回的消息。代码如下:

  // 1.WSHttpBinding_IWCFService
             using  (WCFServiceClient wcfServiceProxyHttp  =   new  WCFServiceClient( " WSHttpBinding_IWCFService " ))
            {
                
string  strUserName  =   " Frank Xu Lei WSHttpBinding  " ;
                
string  strMessage  =   "" ;
                
// 通过代理调用SayHelloToUser服务
                strMessage  = wcfServiceProxyHttp.SayHelloToUser(strUserName);
                Console.WriteLine(strMessage);
            }
            
// 2.NetTcpBinding_IWCFService
             using  (WCFServiceClient wcfServiceProxyHttp  =   new  WCFServiceClient( " WSHttpBinding_IWCFService " ))
            {
                
string  strUserName  =   " Frank Xu Lei NetTcpBinding  " ;
                
string  strMessage  =   "" ;
                
// 通过代理调用SayHelloToUser服务
                strMessage  =  wcfServiceProxyHttp.SayHelloToUser(strUserName);
                Console.WriteLine(strMessage);
            }
            
// 3.BasicHttpBinding_IWCFService
             using  (WCFServiceClient wcfServiceProxyHttp  =   new  WCFServiceClient( " WSHttpBinding_IWCFService " ))
            {
                
string  strUserName  =   " Frank Xu Lei BasicHttpBinding  " ;
                
string  strMessage  =   "" ;
                
// 通过代理调用SayHelloToUser服务
                strMessage  =  wcfServiceProxyHttp.SayHelloToUser(strUserName);
                Console.WriteLine(strMessage);
            }
            
// 4.WSDualHttpBinding_IWCFService,
             using  (WCFServiceClient wcfServiceProxyHttp  =   new  WCFServiceClient( " WSHttpBinding_IWCFService " ))
            {
                
string  strUserName  =   " Frank Xu Lei WSDualHttpBinding  " ;
                
string  strMessage  =   "" ;
                
// 通过代理调用SayHelloToUser服务
                strMessage  =  wcfServiceProxyHttp.SayHelloToUser(strUserName);
                Console.WriteLine(strMessage);
            }

【3.4】测试结果:

    启动宿主、客户端,进行测试测试。结果如图:

【4】总结:

    1)以上测试可以看出,客户端的每次请求,服务端都可以获取响应的地址信息:IP+Port.获得以后大家可以再进行别的处理,比如系统日志LOG、安全限制等等。

    2)此特性只是对http和tcp相关的绑定器作用,其它绑定WCF没有做支持,和实际绑定的应用有关系。比如NamePipe等。

    3)双向通信,这个属性可以获取服务端的信息。

    4)这个属性没做欺骗检测,如果使用作为安全标准,要慎重考虑。

     以上就是WCF获取客户端机制的介绍和代码实现的讲解部分,大家基本实际项目开发可以考虑结合自身情况使用。 最后给出实现代码,可以直接运行,版本是VS2008 RTM.NET3.5,大家调试的时候注意版本兼容问题。下载地址如下:

/Files/frank_xl/WCFServiceGetClientAddressFrankXuLei.rar。有问题大家可以留言交流,也可以到MSDN中文论坛交流:http://social.microsoft.com/Forums/zh-CN/wcfzhchs/threads

参考文章:

1.CSDN的讨论帖子:http://topic.csdn.net/u/20071226/16/53457f70-e80c-46a6-8dc2-39359ba3433a.html

2.老外的博客:Client IP addresses in Orcas:

http://blogs.msdn.com/phenning/archive/2007/08/08/remoteendpointmessageproperty-in-wcf-net-3-5.aspx,VS2008里提供了实现方法。

 

 


老徐的博客

【作者】:Frank Xu Lei

【地址】:http://www.cnblogs.com/frank_xl/archive/2009/06/24/1509840.html

 

转载于:https://www.cnblogs.com/cpcpc/archive/2011/02/17/2123062.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值