WCF NamedPipe CommunicationException - “管道已结束。(109,0x6d)。”

时间:2013-04-05 14:14:19

标签: c# wcf windows-services named-pipes

我正在编写带有“状态工具”的Windows服务。该服务托管一个名为管道端点的WCF,用于进程间通信。通过命名管道,状态工具可以定期查询服务以获取最新的“状态”。

enter image description here

在我的开发机器上,我有多个IP地址;其中一个是具有192.168.1.XX地址的“本地”网络。另一个是“公司”网络,具有10.0.X.XX地址。 Windows服务在单个IP地址上收集UDP多播流量。

到目前为止,Windows服务只要使用“192.168.1.XX”地址就可以正常工作。它始终正确地向客户报告状态。

当我切换到另一个“公司”IP地址(10.0.X.XX)并重新启动服务时,我会在检索状态时获得连续的“CommunicationExceptions”:

"There was an error reading from the pipe: The pipe has been ended. (109, 0x6d)."

现在,我不认为UDP客户端'声称'的IP地址应该与Named-Pipe接口的功能有关;它们完全是应用程序的独立部分!

以下是相关的WCF配置部分:

//On the Client app:
string myNamedPipe = "net.pipe://127.0.0.1/MyNamedPipe";
ChannelFactory<IMyService> proxyFactory =
    new ChannelFactory<IMyService>(
        new NetNamedPipeBinding(),
        new EndpointAddress(myNamedPipe));


//On the Windows Service:
string myNamedPipe = "net.pipe://127.0.0.1/MyNamedPipe";
myService = new MyService(myCustomArgs);
serviceContractHost = new ServiceHost(myService );
serviceContractHost.AddServiceEndpoint(
    typeof(IMyService),
    new NetNamedPipeBinding(),
    myNamedPipe);

serviceContractHost.Open();

我不认为这是一个'权限'问题 - 我正在运行具有管理权限的客户端 - 但也许有一些特定于域的原因导致了这一点?

9 个答案:

答案 0 :(得分:11)

事实证明,IP地址是一个完整的红色鲱鱼。

异常的真正原因是WCF服务返回了无效的Enum值。

我的枚举是这样定义的:

[DataContract]
public enum MyEnumValues : Byte
{
    [EnumMember]
    Enum1 = 0x10,
    [EnumMember]
    Enum2 = 0x20,
    [EnumMember]
    Enum3 = 0x30,
    [EnumMember]
    Enum4 = 0x40,
} 

表面看起来很好。

但是底层服务报告的原始状态是&#34; 0的字节值,&#34;并且没有相应的枚举值可用于投射它。

一旦我确保Enum值全部有效,该工具就会像圣诞树一样点亮。

如有疑问,请假设您的WCF数据无效。

答案 1 :(得分:4)

此异常表示服务器端存在序列化问题。

通过查看跟踪文件(svclog)可以解决此问题。要打开跟踪,请使用以下配置:

<system.diagnostics>
        <sources>
            <source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="false">
                <listeners>
                    <add name="traceListener" />
                </listeners>
            </source>
            <source name="System.ServiceModel.MessageLogging">
                <listeners>
                    <add name="traceListener" />
                </listeners>
            </source>
        </sources>
        <sharedListeners>
            <add name="traceListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="C:\Remos\Log\WcfTraceServer.svclog" />
        </sharedListeners>
    </system.diagnostics>

就我而言,我正在序列化一个不在枚举中的值。

答案 2 :(得分:3)

有同样的问题There was an error reading from the pipe: Unrecognized error 109 (0x6d).

  • 一个原因是客户端和服务器<netNamedPipeBinding> <security mode="None"></security>...之间不一致绑定(无通信)
  • 另一个间歇性问题与超时有关。

两者都有相同的顶部错误消息。

在服务器和客户端绑定中增加超时会使问题重新出现。

设置得太低的绑定超时时间:

sendTimeout="00:00:05" receiveTimeout="00:00:05"

堆栈追踪: at System.ServiceModel.Channels.StreamConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout) at System.ServiceModel.Channels.SessionConnectionReader.Receive(TimeSpan timeout) at System.ServiceModel.Channels.SynchronizedMessageSource.Receive(TimeSpan timeout) at System.ServiceModel.Channels.TransportDuplexSessionChannel.Receive(TimeSpan timeout) at System.ServiceModel.Channels.TransportDuplexSessionChannel.TryReceive(TimeSpan timeout, Message& message) at System.ServiceModel.Dispatcher.DuplexChannelBinder.Request(Message message, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs) at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

答案 3 :(得分:2)

当返回的有效负载太大时,这发生在我的WCF服务中。通过在app.config中的serviceBehavior中添加它来修复它:

let closeBarButtonItem = UIBarButtonItem(barButtonSystemItem:UIBarButtonSystemItem.Stop, target: SomeType.self, action: "someMethod")

答案 4 :(得分:1)

当服务操作抛出并且通道出现故障时,我收到此错误。在您的情况下,您已经验证了服务操作正确完成并且只返回了投票,但如果有疑问,请确保服务操作运行正常。

答案 5 :(得分:1)

我有很多没有设置{}的属性。添加这个解决了我的问题。

答案 6 :(得分:0)

同样的问题,但感谢Wojciechanswer

我不得不进行更多挖掘以找到放置<security>标记的位置,所以这里是system.serviceModel部分的开始现在看起来......

<system.serviceModel>
   <bindings>
     <netNamedPipeBinding>
       <binding>
         <security mode="None"></security>
       </binding>
     </netNamedPipeBinding>
   </bindings>
   ....

答案 7 :(得分:0)

我遇到了这个问题,因为我使用的是older tutorial,并尝试以编程方式进行配置。

我缺少的部分是提供元数据端点(thank you, this post!)。

ServiceMetadataBehavior serviceMetadataBehavior = 
    host.Description.Behaviors.Find<ServiceMetadataBehavior>();

if (serviceMetadataBehavior == null)
{
    serviceMetadataBehavior = new ServiceMetadataBehavior();
    host.Description.Behaviors.Add(serviceMetadataBehavior);
}

host.AddServiceEndpoint(
    typeof(IMetadataExchange), 
    MetadataExchangeBindings.CreateMexNamedPipeBinding(), 
    "net.pipe://localhost/PipeReverse/mex"
);

答案 8 :(得分:0)

为了添加到组合中,我们的代码正在序列化一个 Dictionary<string, List<int>>。这似乎引起了问题。使用 [DataContract] 标记类和每个要序列化的公共属性(包括 Dictionary)为我们解决了这个问题。

<DataContract>
Public Class QueryConfig

    <DataMember>
    Public SegmentTypes As List(Of SegmentType)

    <DataMember>
    Public Events As Dictionary(Of String, List(Of Integer))

    <DataMember>
    Public Enabled As Boolean

    <DataMember>
    Public Name As String