第二篇:聊聊binding

上一篇构建的WCF程序,binding指定的是basicHttpBinding,这是最基础的通讯方式,基于http,不加密,抓一下包的话,应该是这样的:

  1. 发送包:

  2. POST /wcf HTTP/1.1

  3. Content-Type: text/xml; charset=utf-8

  4. SOAPAction: "WCF.Demo/IData/SayHello"

  5. Host: 127.0.0.1:8080

  6. Content-Length: 156

  7. Expect: 100-continue

  8. Connection: Keep-Alive

  9. <s:Envelopexmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><SayHelloxmlns="WCF.Demo"><userName>WCF</userName></SayHello></s:Body></s:Envelope>

  10. -------------------------

  11. 应答包:

  12. HTTP/1.1 100 Continue

  13. HTTP/1.1 200 OK

  14. Content-Length: 191

  15. Content-Type: text/xml; charset=utf-8

  16. Server: Microsoft-HTTPAPI/2.0

  17. Date: Mon, 05 Mar 2012 08:45:31 GMT

  18. <s:Envelopexmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><SayHelloResponsexmlns="WCF.Demo"><SayHelloResult>Hello WCF.</SayHelloResult></SayHelloResponse></s:Body></s:Envelope>

就是SOAP,和WebService是一样的。basicHttpBinding的优势在于通用,又基于http,所以在跨语言的开发中或者是穿透复杂网络环境时占优势,但是效率比较低,因为SOAP的序列化和反序列化比较耗时,传输的数据量也比较大,而且是明文,安全性差。

WCF的binding有很多种,包括:

basicHttpBinding(常用) 符合WSBasicProfile 1.1标准,以提供最大的互操作性
wsHttpBinding(常用) 符合WS-*协议的HTTP通讯,加密
wsDualHttpBinding 双工http通信,初始信息的接收者不会直接响应发送者,而是可以在一定时间之内传送任意次的响应
wsFederationBinding http通信,对服务资源的访问可以根据一个显式确定的凭据提供程序发出的凭据加以控制
netTcpBinding(常用) 提供网络里WCF软件实体之间的安全可靠高性能的通信
netNamedPipeBinding 同一台机器上的WCF软件实体之间的安全可靠高性能的通信
netMsmqBinding WCF软件实体与其它软件实体间通过MSMQ通信
msmqIntegrationBinding 软件实体与其它软件实体间通过MSMQ通信
netPeerTcpBinding WCF软件实体间通过Windows对等网络技术通信

内容很多,我们挑wsHttpBinding和netTcpBinding继续研究一下,这两个最有代表性。在上一篇demo的基础上修改一下。

1、服务端

服务端的功能逻辑没有任何变化,只是调整绑定方式,所以只调整App.config:

  1. <?xmlversion="1.0"encoding="utf-8"?>

  2. <configuration>

  3. <system.serviceModel>

  4. <services>

  5. <servicename="Server.DataService">

  6. <host>

  7. <baseAddresses>

  8. <addbaseAddress="http://localhost:8080/wcf"/>

  9. <!-- 此处增加了个baseAddress,注意标头指定的是net.tcp,另外端口不能被占用 -->

  10. <addbaseAddress="net.tcp://localhost:8081/wcf"/>

  11. </baseAddresses>

  12. </host>

  13. <!-- 此处调整了绑定使用wsHttpBinding方式 -->

  14. <endpointaddress=""binding="wsHttpBinding"contract="Server.IData"/>

  15. <!-- 此处增加了一个endpoint,使用netTcpBinding方式,服务契约同样是IData -->

  16. <endpointaddress=""binding="netTcpBinding"contract="Server.IData"/>

  17. </service>

  18. </services>

  19. </system.serviceModel>

  20. </configuration>

与之前相比,增加了一个baseAddress和一个endpoint,另外调整了之前endpoint的绑定方式。现在针对同一个服务契约,有两个endpoint了,但是它们不会冲突,因为两者的网络协议不同,所以wsHttpBinding的会使用http://localhost:8080/wcf的地址,而netTcpBinding的会使用net.tcp://localhost:8081/wcf的地址。

如果同时定义了basicHttpBinding和wsHttpBinding呢?那么它们的address一定不能相同,因为baseAddress已经相同了,adress还一样,就无法访问了。

编译运行一下,然后命令行“netstat -ano”看一下,应该能看到8080和8081都开始监听了。

  1. TCP    0.0.0.0:8080        0.0.0.0:0          LISTENING       4

  2. TCP    0.0.0.0:8081        0.0.0.0:0          LISTENING       692

  3. TCP    [::]:8080           [::]:0             LISTENING       4

  4. TCP    [::]:8081           [::]:0             LISTENING       692

TCP 8081端口的PID显示是我们的服务程序在对外监听。


2、客户端

由于服务端修改了绑定方式,客户端必须要与之匹配,先修改App.config文件:

  1. <?xmlversion="1.0"encoding="utf-8"?>

  2. <configuration>

  3. <system.serviceModel>

  4. <client>

  5. <!-- 此处调整了binding为wsHttpBinding -->

  6. <endpointname="httpDataService"address="http://localhost:8080/wcf"binding="wsHttpBinding"contract="Server.IData"/>

  7. <!-- 此处新增了一个endpoint,指定使用netTcpBinding方式 -->

  8. <endpointname="tcpDataService"address="net.tcp://localhost:8081/wcf"binding="netTcpBinding"contract="Server.IData"/>

  9. </client>

  10. </system.serviceModel>

  11. </configuration>

需要指出的是,服务端开放了2种访问方式,客户端不一定也要写2个endpoint,这里是为了测试两种绑定。

调用代码也要做个小修改:

  1. using System;

  2. using System.ServiceModel;

  3. using System.ServiceModel.Channels;

  4. namespace Client

  5. {

  6. class Program

  7. {

  8. staticvoid Main(string[] args)

  9. {

  10. //定义一个http方式的代理,配置使用httpDataService中的定义

  11. var httpProxy = new ChannelFactory<Server.IData>("httpDataService").CreateChannel();

  12. Console.WriteLine(httpProxy.SayHello("WCF"));

  13. ((IChannel)httpProxy).Close();

  14. //定义一个tcp方式的代理,配置使用tcpDataService中的定义

  15. var tcpProxy = new ChannelFactory<Server.IData>("tcpDataService").CreateChannel();

  16. Console.WriteLine(tcpProxy.SayHello("WCF"));

  17. ((IChannel)tcpProxy).Close();

  18. }

  19. }

  20. }

编译运行一下,应该能够输出两行 Hello WCF.。

抓包看看:

wsHttpBinding方式的客户端与服务端总共交换了60多个数据包,这是因为双方要先握手交换密钥,另外由于数据加了密,长度也变大了。这里只截第一次交互的数据看看:

  1. 发送包:

  2. POST /wcf HTTP/1.1

  3. Content-Type: application/soap+xml; charset=utf-8

  4. Host: 127.0.0.1:8080

  5. Content-Length: 1106

  6. Expect: 100-continue

  7. Connection: Keep-Alive

  8. <s:Envelopexmlns:s="http://www.w3.org/2003/05/soap-envelope"xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><a:Actions:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</a:Action><a:MessageID>urn:uuid:144b8aeb-6ac1-46f5-8361-957425b827c8</a:MessageID><a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></a:ReplyTo><a:Tos:mustUnderstand="1">http://192.168.90.81:8080/wcf</a:To></s:Header><s:Body><t:RequestSecurityTokenContext="uuid-156d27d6-3db7-43ac-b488-12f9ae123861-1"xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust"><t:TokenType>http://schemas.xmlsoap.org/ws/2005/02/sc/sct</t:TokenType><t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType><t:KeySize>256</t:KeySize><t:BinaryExchangeValueType="http://schemas.xmlsoap.org/ws/2005/02/trust/spnego"EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">TlRMTVNTUAABAAAAt7IY4gkACQAxAAAACQAJACgAAAAGAbAdAAAAD1RJQU5ZVS1QQ1dPUktHUk9VUA==</t:BinaryExchange></t:RequestSecurityToken></s:Body></s:Envelope>

  9. ---------------------

  10. 应答包:

  11. HTTP/1.1 100 Continue

  12. HTTP/1.1 200 OK

  13. Content-Length: 1044

  14. Content-Type: application/soap+xml; charset=utf-8

  15. Server: Microsoft-HTTPAPI/2.0

  16. Date: Tue, 06 Mar 2012 01:46:24 GMT

  17. <s:Envelopexmlns:s="http://www.w3.org/2003/05/soap-envelope"xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><a:Actions:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue</a:Action><a:RelatesTo>urn:uuid:144b8aeb-6ac1-46f5-8361-957425b827c8</a:RelatesTo></s:Header><s:Body><t:RequestSecurityTokenResponseContext="uuid-156d27d6-3db7-43ac-b488-12f9ae123861-1"xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust"xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><t:BinaryExchangeValueType="http://schemas.xmlsoap.org/ws/2005/02/trust/spnego"EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">TlRMTVNTUAACAAAAEgASADgAAAA1wprik+hmjwEji3X4ciEAAAAAAGgAaABKAAAABgGwHQAAAA9UAEkAQQBOAFkAVQAtAFAAQwACABIAVABJAEEATgBZAFUALQBQAEMAAQASAFQASQBBAE4AWQBVAC0AUABDAAQAEgBUAGkAYQBuAFkAdQAtAFAAQwADABIAVABpAGEAbgBZAHUALQBQAEMABwAIAPm5CvA6+8wBAAAAAA==</t:BinaryExchange></t:RequestSecurityTokenResponse></s:Body></s:Envelope>

应该是双方交换了一个256位的密钥,反正所有的数据交互都不再是明文的了。

再来看netTcpBinding的这次,还是只截一小段吧:

  1. 发送包:

  2. 00000000  00 01 00 01 02 02 20 6E  65 74 2E 74 63 70 3A 2F   ...... n et.tcp:/

  3. 00000010  2F 31 39 32 2E 31 36 38  2E 39 30 2E 38 31 3A 38   /192.168 .90.81:8

  4. 00000020  30 38 31 2F 77 63 66 03  08 09 15 61 70 70 6C 69   081/wcf. ...appli

  5. 00000030  63 61 74 69 6F 6E 2F 6E  65 67 6F 74 69 61 74 65   cation/n egotiate

  6. 00000040  16 01 00 00 3A 4E 54 4C  4D 53 53 50 00 01 00 00   ....:NTL MSSP....

  7. 00000050  00 B7 B2 18 E2 09 00 09  00 31 00 00 00 09 00 09   ........ .1.....

  8. ----------

  9. 应答包:

  10. 00000000  0A 16 01 00 00 B2 4E 54  4C 4D 53 53 50 00 02 00   ......NT LMSSP...

  11. 00000010  00 00 12 00 12 00 38 00  00 00 35 C2 9A E2 3A D5   ......8. ..5...:.

  12. 00000020  19 64 33 D4 B9 7C F8 72  21 00 00 00 00 00 68 00   .d3..|.r !.....h.

  13. 00000030  68 00 4A 00 00 00 06 01  B0 1D 00 00 00 0F 54 00   h.J..... ......T.

  14. 00000040  49 00 41 00 4E 00 59 00  55 00 2D 00 50 00 43 00   I.A.N.Y. U.-.P.C.

  15. 00000050  02 00 12 00 54 00 49 00  41 00 4E 00 59 00 55 00   ....T.I. A.N.Y.U.

从效率上讲,tcp方式要比http方式高得多,同时http方式,basicHttpBinding又要比wsHttpBinding高得多,在实际使用中,大家要看需求来决定使用哪种方式。

OK,下一篇我们看看能不能不用写复杂的配置就发布WCF服务,也以此来加深一下对Host、Contract、Binding、BaseAddress的理解。

本文出自 “兔子窝” 博客,请务必保留此出处http://boytnt.blog.51cto.com/966121/796993

转载于:https://blog.51cto.com/rmlifejun/1264398

WCF简单教程(2) 聊聊binding相关推荐

  1. wcf简单教程(10) ajax调用,wcf简单教程(10) ajax调用

    wcf简单教程(10) ajax调用 [2021-02-11 16:23:59]  简介: php去除nbsp的方法:首先创建一个PHP代码示例文件:然后通过"preg_replace(&q ...

  2. WCF简单教程(8) 安全 - Windows认证

    第八篇:WCF安全 WCF提供了非常丰富的加密机制与审核机制,以保证对外提供的服务安全可靠.本文是简单教程,所以只挑其中的一小部分来聊聊. 先来看看最简单的Windows认证. 所谓Windows认证 ...

  3. WCF简单教程(5) 用IIS做Host

    第五篇:用IIS做Host 之前几篇的Demo中,我们一直在用控制台程序做Server,今天换IIS来做Host,在Web Application中添加WCF的服务. 其实在Web Applicati ...

  4. WCF简单教程(6) 单向与双向通讯

    第六篇:单向与双向通讯 项目开发中我们时常会遇到需要异步调用的问题,有时忽略服务端的返回值,有时希望服务端在需要的时候回调,今天就来看看在WCF中如何实现. 先看不需要服务端返回值的单向调用,老规矩, ...

  5. WCF简单教程(4) 数据契约

    第四篇:用数据契约传递自定义数据对象 之前的演示中,我们一直都是在用string类型做参数和返回值,实际项目中肯定会传递自定义的数据类型.与WebService不同,WCF想传递自定义数据,必须要将其 ...

  6. 无废话WCF系列教程 -- 李林峰

    李林峰的无废话WCF入门教程 无废话WCF入门教程一[什么是WCF] 无废话WCF入门教程二[WCF应用的通信过程] 无废话WCF入门教程三[WCF的宿主] 无废话WCF入门教程四[WCF的配置文件] ...

  7. ASP.NET Core 异常和错误处理 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core 异常和错误处理 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 异常和错误处理 上一章节中,我们学习了 ASP.NET Cor ...

  8. idea 从svn导入多个项目_IDEA导入项目简单教程

    该教程用于IDEA初学者导入eclipse项目,或者导入其他已经写好的Java源程序的简单教程. 我们用IDEA打开一个已经写好的项目源文件时,如果没有配置好,就会出现:JDK配置失误报错.程序无法启 ...

  9. expect简单教程

    expect简单教程 一.概述 expect是Unix系统中用来进行自动化控制和测试的软件工具,由Don Libes制作,作为Tcl脚本语言的一个扩展,应用在交互式软件中如telnet,ftp,Pas ...

  10. 一步一个脚印学习WCF系列之WCF基础术语—绑定(Binding)(五)

    阅读目录 一:为什么会出现绑定? 一:为什么会出现绑定? . 服务之间的通信是多种多样的,有很多种通信模式 . 消息通信模式就有比如:同步请求/应答模式,异步的即发即弃消息等一系列,传递消息的传输协议 ...

最新文章

  1. web中的cookies以及作用--web testing 学习笔记
  2. 轻量级HTTP服务器Nginx(配置与调试Nginx)
  3. Python-random模块-59
  4. checking size of char… configure: error: cannot compute sizeof (char) 解决方法
  5. 树莓派 Raspberry Pi 更换国内源
  6. java开发 职业技能_java编程开发程序员需要具备哪些职业技能
  7. python3 安装Crypto 出现的问题
  8. 补习系列(9)-springboot 定时器,你用对了吗
  9. PHP header发送各种类型文件及设置文件下载名
  10. 天体物理科研作图格式-要求-plot_example.py
  11. 读SUCH AMERCAN和贾平凹的画集
  12. 济南学习 Day 5 T1 晚
  13. Python标准库——turtle库
  14. python全套 百度云-2018年6月北京黑马python24期全套视频课程
  15. 如何用用计算机名访问共享打印机,局域网怎么连接共享打印机共享
  16. 浪潮nf5280m5默认ipmi_NF5180M5- IPMI设置
  17. ColdFusion mx 7.0 函数分类列表
  18. 高德SDK 小车轨迹回放,速度、进度控制
  19. idea当中批量替换变量名字
  20. 如何在腾讯地图绘制自己的坐标

热门文章

  1. 学习HanNLP2015年12月4日 16:24:53
  2. 分类战车SVM (第四话:拉格朗日对偶问题)
  3. 微积分中BW定理指的是什么
  4. 每日一题/014/三角函数/和差化积/求证:cos 2+cos 4+cos 6+...+cos 2n=sin ncos(n+1)/sin1
  5. HW护网即将开始4.6
  6. 147.有序数组的TwoSum(力扣leetcode) 博主可答疑该问题
  7. java byte 相等比较_Java字节码跟真正汇编的比较
  8. 求链表是否有环,及环入口,环长度
  9. C++11模板友元语法
  10. c#的const可以用于引用类型吗