转帖记录一下,以便日后使用。

主要使用是.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】宿主

<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

WCF service 获取 client 端的 IP 和 port (转)的更多相关文章

  1. 用C#基于WCF创建TCP的Service供Client端调用

    本文将详细讲解用C#基于WCF创建TCP的Service供Client端调用的详细过程 1):首先创建一个Windows Service的工程 2):生成的代码工程结构如下所示 3):我们将Servi ...

  2. server端获得到client端的IP地址的格式

    使用telnet,ping或其他client连接server端时,server端获得的client端的ip地址取决于client端使用的时ipv4还是ipv6地址. 例: client IPv4地址: ...

  3. python - socket - client端指定ip和端口

    问题描述: 在设备中有3个NI, ip分别为192.168.1.5/6/7.其中本端192.168.1.6同对端192.168.1.10建立了一个tunnel. 我希望测试tunnel连通性, 对端起 ...

  4. WCF客户端获取服务端异常[自定义异常]

    引言 经过不断的摸索,询问/调试,终于学会了关于WCF客户端与服务端之间异常的处理机制,在此来记录自己的成果,用于记录与分享给需要的伙伴们. 首先感谢[.NET技术群]里群主[轩]的大力帮助,如有需要 ...

  5. [Python Study Notes]CS架构远程访问获取信息--Client端v2.0

    更新内容: 1.增加内存信息获取 2.增加电池信息获取 3.增加磁盘信息获取 4.重新布局窗体 5.增加窗体名称 6.增加连接成功之前,不可按压 效果图: '''''''''''''''''''''' ...

  6. [Python Study Notes]CS架构远程访问获取信息--Client端v1.0

    更新内容: 1.添加entry栏默认ip和port口 2.修正退出功能 3.添加退出自动关闭窗口功能 4.优化cpu显示为固定保留两位小数 '''''''''''''''''''''''''''''' ...

  7. [Python Study Notes]CS架构远程访问获取信息--Client端

    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ...

  8. 通过网络socket获取对方 ip 和port

    int getpeername(int s, struct sockaddr *name, socklen_t *namelen);描述获取socket的对方地址struct sockaddr_in ...

  9. If WCF Service side and Client side config is different?!

    from stackoverflow http://stackoverflow.com/questions/4879310/when-setting-up-a-wcf-client-and-serve ...

随机推荐

  1. 【笔记5】用pandas实现矩阵数据格式的推荐算法 (基于物品的协同)

    ''' 基于物品的协同推荐 矩阵数据 说明: 1.修正的余弦相似度是一种基于模型的协同过滤算法.我们前面提过,这种算法的优势之 一是扩展性好,对于大数据量而言,运算速度快.占用内存少. 2.用户的评价 ...

  2. 用table做网页,设置了border为1px怎么还是觉得很粗?

    设置边框重叠 border-collapse:collapse;  /*边框重叠*/ 例: <table width="700" style="border-col ...

  3. knockoutJS学习笔记07:绑定上下文

    所谓绑定上下文就是当前绑定(dat-bind)所使用到的对象(ViewModel).在单个对象绑定的情况下是很容易理解的,但对象可能是复杂的类型,嵌套很多层,这个时候每层都有自己的上下文对象,理解起来 ...

  4. Linux 中 Oracle dmp 文件导入导出

    a. 用户名 system 密码 manager 导出到D:/daochu.dmp中 exp system/manager@SID file=d:/daochu.dmp full=y b. 将数据库中 ...

  5. myeclipse 注释模板

    选中你要加注释的方法或类,按 Alt + shift + J.  

  6. URL类

    java.net.URL类是对统一资源定位符(如http://www.lolcats.com)的抽象.它扩展了java.lang.Object,是一个final类.它采用策略模式,协议处理器(prot ...

  7. Git 命令速查图

  8. VIM编辑器简单总结

    第一讲小结  1. 光标在屏幕文本中的移动既可以用箭头键,也可以使用 hjkl 字母键.         h (左移)       j (下行)       k (上行)     l (右移)  2. ...

  9. jQuery链式操作[转]

    用过jQuery的朋友都知道他强大的链式操作,方便,简洁,易于理解,如下 $("has_children").click(function(){ $(this).addClass( ...

  10. 点击某个按钮在tableView某个位置动态插入一行cell

    实现步骤: 1.修改数据模型数组 给模型数组的某个位置增加一个模型 2.执行以下代码 NSIndexPath *indexPath = [NSIndexPath indexPathForRow: in ...