最近在改进一个wcf程序时碰到了一个常见的问题,监听端口号冲突。按道理这种问题多半发生在同一个监听程序开了多个或者有其他程序占用了端口号引起的。于是按照常规的方式去检查,原以为一个很容易解决的问题,折腾了一小会没找出原因,以至于重启电脑这样的伎俩也用上了还没解决。怀疑是不是程序太复杂了,于是对程序进行了精简,仅保留了wcf相关的配置内容,如下:
原配置文件
1 <configuration>
2 <system.serviceModel>
3 <services>
4 <service name="ComplexDataService.MyService" behaviorConfiguration="mexConfig">
5 <host>
6 <baseAddresses>
7 <add baseAddress="net.tcp://localhost:1955/MyService"/>
8 </baseAddresses>
9 </host>
10 <endpoint address="" binding="netTcpBinding" bindingConfiguration="NoneSecurityAndMoreSize" contract="ComplexDataService.IMyService"/>
11 <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
12 </service>
13 </services>
14 <behaviors>
15 <serviceBehaviors>
16 <behavior name="mexConfig">
17 <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:1956/MyService"/>
18 <serviceThrottling maxConcurrentCalls="10" maxConcurrentInstances="10" maxConcurrentSessions="10"/>
19 <serviceDebug includeExceptionDetailInFaults="true"/>
20 </behavior>
21 </serviceBehaviors>
22 </behaviors>
23 <bindings>
24 <netTcpBinding>
25 <binding name="NoneSecurityAndMoreSize" maxBufferPoolSize="1048576" maxBufferSize="524288" maxConnections="20" maxReceivedMessageSize="524288">
26 <readerQuotas maxStringContentLength="524288" />
27 <security mode="None" />
28 </binding>
29 </netTcpBinding>
30 </bindings>
31 </system.serviceModel>
32 </configuration>
2 <system.serviceModel>
3 <services>
4 <service name="ComplexDataService.MyService" behaviorConfiguration="mexConfig">
5 <host>
6 <baseAddresses>
7 <add baseAddress="net.tcp://localhost:1955/MyService"/>
8 </baseAddresses>
9 </host>
10 <endpoint address="" binding="netTcpBinding" bindingConfiguration="NoneSecurityAndMoreSize" contract="ComplexDataService.IMyService"/>
11 <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
12 </service>
13 </services>
14 <behaviors>
15 <serviceBehaviors>
16 <behavior name="mexConfig">
17 <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:1956/MyService"/>
18 <serviceThrottling maxConcurrentCalls="10" maxConcurrentInstances="10" maxConcurrentSessions="10"/>
19 <serviceDebug includeExceptionDetailInFaults="true"/>
20 </behavior>
21 </serviceBehaviors>
22 </behaviors>
23 <bindings>
24 <netTcpBinding>
25 <binding name="NoneSecurityAndMoreSize" maxBufferPoolSize="1048576" maxBufferSize="524288" maxConnections="20" maxReceivedMessageSize="524288">
26 <readerQuotas maxStringContentLength="524288" />
27 <security mode="None" />
28 </binding>
29 </netTcpBinding>
30 </bindings>
31 </system.serviceModel>
32 </configuration>
经过了瘦身之后,问题依然存在,那么可以确定是在service本身出错了。翻看之前学习wcf时写的简单练习,发现都没有这个问题,唯一不同在于配置没这么负责。于是继续精简配置,去掉bindingConfiguration="NoneSecurityAndMoreSize"之后,世界就和谐了,没哟报端口冲突的错误。再进一步从NoneSecurityAndMoreSize对应的配置下手,问题终于定位在maxConnections="20"这个属性中。去掉maxConnections之后就不会出现问题。
问题找到之后,就必须找解决方案。经过简单搜索之后发现同样问题其他人也遇到过,微软给出的解决方案是修改配置,使支持端口号共享。之前也听说过,但没有实际用上,解决方案也相对简单,只需要修改配置即可。关键配置是设置 netTcpBinding 中的portSharingEnabled为true,同时对于mex需要自定义个customBinding,支持portSharingEnabled。并将这些配置应用到对应的endpoint中。
修改后的配置
1 <configuration>
2 <system.serviceModel>
3 <services>
4 <service name="ComplexDataService.MyService" behaviorConfiguration="mexConfig">
5 <host>
6 <baseAddresses>
7 <add baseAddress="net.tcp://localhost:1955/MyService"/>
8 </baseAddresses>
9 </host>
10 <endpoint address="" binding="netTcpBinding" bindingConfiguration="NoneSecurityAndMoreSize" contract="ComplexDataService.IMyService"/>
11 <endpoint address="mex" binding="customBinding" bindingConfiguration="myMexTcpBinding" contract="IMetadataExchange"/>
12 </service>
13 </services>
14 <behaviors>
15 <serviceBehaviors>
16 <behavior name="mexConfig">
17 <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:1956/MyService"/>
18 <serviceThrottling maxConcurrentCalls="10" maxConcurrentInstances="10" maxConcurrentSessions="10"/>
19 <serviceDebug includeExceptionDetailInFaults="true"/>
20 </behavior>
21 </serviceBehaviors>
22 </behaviors>
23 <bindings>
24 <customBinding>
25 <binding name="myMexTcpBinding">
26 <tcpTransport portSharingEnabled="true"/>
27 </binding>
28 </customBinding>
29 <netTcpBinding>
30 <binding name="NoneSecurityAndMoreSize" maxBufferPoolSize="1048576" maxBufferSize="524288" maxConnections="20" maxReceivedMessageSize="524288" portSharingEnabled="true">
31 <readerQuotas maxStringContentLength="524288" />
32 <security mode="None" />
33 </binding>
34 </netTcpBinding>
35 </bindings>
36 </system.serviceModel>
37 </configuration>
2 <system.serviceModel>
3 <services>
4 <service name="ComplexDataService.MyService" behaviorConfiguration="mexConfig">
5 <host>
6 <baseAddresses>
7 <add baseAddress="net.tcp://localhost:1955/MyService"/>
8 </baseAddresses>
9 </host>
10 <endpoint address="" binding="netTcpBinding" bindingConfiguration="NoneSecurityAndMoreSize" contract="ComplexDataService.IMyService"/>
11 <endpoint address="mex" binding="customBinding" bindingConfiguration="myMexTcpBinding" contract="IMetadataExchange"/>
12 </service>
13 </services>
14 <behaviors>
15 <serviceBehaviors>
16 <behavior name="mexConfig">
17 <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:1956/MyService"/>
18 <serviceThrottling maxConcurrentCalls="10" maxConcurrentInstances="10" maxConcurrentSessions="10"/>
19 <serviceDebug includeExceptionDetailInFaults="true"/>
20 </behavior>
21 </serviceBehaviors>
22 </behaviors>
23 <bindings>
24 <customBinding>
25 <binding name="myMexTcpBinding">
26 <tcpTransport portSharingEnabled="true"/>
27 </binding>
28 </customBinding>
29 <netTcpBinding>
30 <binding name="NoneSecurityAndMoreSize" maxBufferPoolSize="1048576" maxBufferSize="524288" maxConnections="20" maxReceivedMessageSize="524288" portSharingEnabled="true">
31 <readerQuotas maxStringContentLength="524288" />
32 <security mode="None" />
33 </binding>
34 </netTcpBinding>
35 </bindings>
36 </system.serviceModel>
37 </configuration>
不知道为什么设置了maxConnections之后就出问题,还需进一步了解。
具体可参考