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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15836199/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 18:08:00  来源:igfitidea点击:

WCF NamedPipe CommunicationException - "The pipe has been ended. (109, 0x6d)."

c#wcfwindows-servicesnamed-pipes

提问by BTownTKD

I am writing a Windows Service with accompanying "status tool." The service hosts a WCF named pipe endpoint for inter-process communication. Through the named pipe, the status tool can periodically query the service for the latest "status."

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

enter image description here

在此处输入图片说明

On my development machine, I have multiple IP Addresses; one of them is a "local" network with a 192.168.1.XX address. The other is the "corporate" network, with a 10.0.X.XX address. The Windows Service collects UDP multicast traffic on a single IP Address.

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

The Windows Service has, until now, worked fine as long as it uses the "192.168.1.XX," address. It consistently reports the status correctly to the client.

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

As soon as I switched to the other, "corporate" IP Address (10.0.X.XX) and restarted the service, I get continuous "CommunicationExceptions" when retrieving the status:

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

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

Now, I wouldn't think that the UDP Client's 'claimed' IP address should have anything to do with the functionality of the Named-Pipe interface; they are completely separate pieces of the application!

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

Here are the relevant WCF config sections:

以下是相关的 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();

I wouldn't think this is a 'permissions' issue - I'm running the client with administrative privileges - but perhaps there's some domain-specific reason this broke?

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

采纳答案by BTownTKD

The IP Address was, it turns out, a complete red herring.

事实证明,IP 地址完全是一条红鲱鱼。

The real reason for the exception was invalid Enum values being returned by the WCF service.

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

My enum was defined thusly:

我的枚举是这样定义的:

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

It looks fine on the surface.

表面上看起来不错。

But the raw status reported by the underlying service was a Byte value of "0," and there was no corresponding Enum value for which to cast it.

但是底层服务报告的原始状态是一个 Byte 值“0”,并且没有相应的 Enum 值可以转换它。

Once I ensured that the Enum values were all valid, the tool lit up like a Christmas tree.

一旦我确保 Enum 值都有效,该工具就会像圣诞树一样亮起来。

When in doubt, assume your WCF data is invalid.

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

回答by J S

I got this error when the service operation threw and the channel was actually faulted. In your case, you have already verified that the service operation as such completed correctly and only the return threw, but if there is doubt, make sure the service operation runs OK.

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

回答by Wojciech

Had the same issue There was an error reading from the pipe: Unrecognized error 109 (0x6d).

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

  • One reason was inconsistent bindingbetween client and server <netNamedPipeBinding> <security mode="None"></security>...(no communication)
  • The other intermittent issue was time-out related.
  • 原因之一是客户端和服务器之间的绑定不一致<netNamedPipeBinding> <security mode="None"></security>...(无通信)
  • 另一个间歇性问题与超时有关。

Both had the same top error message.

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

Increasing the time outin the server and client binding stopped issue from reappearing.

增加服务器和客户端绑定的超时时间阻止问题再次出现。

Binding time out that was set too low:

绑定超时设置太低:

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

Stack trace: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)

堆栈跟踪: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)

回答by pizza247

This happened in my WCF service when the payload returned was too big. Fixed it by adding this in a serviceBehavior in app.config:

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

<dataContractSerializer maxItemsInObjectGraph="[some big number]" />

回答by AAAA

Sometimes this error caused by polymorphic feature of objects. for example following service's method will return list of persons:

有时这个错误是由对象的多态特征引起的。例如以下服务的方法将返回人员列表:

[OperationContract]
 List<Person> GetEmployee();

if we have Supervisor class inherited from Person class, and the above method try to return Supervisor Object, the WCF serializer class can not interpret the response, so this error will be raised.
The solution for this problem is to use "known types"or "service known types". we have to specify implicit objects may interact using method or service. For my example, we can put ServiceKnownType attribute in method or service declaration as following code:

如果我们有从 Person 类继承的 Supervisor 类,并且上述方法尝试返回 Supervisor 对象,WCF 序列化程序类无法解释响应,因此将引发此错误
此问题的解决方案是使用“已知类型”“服务已知类型”。我们必须指定隐式对象可以使用方法或服务进行交互。对于我的示例,我们可以将 ServiceKnownType 属性放在方法或服务声明中,如下代码:

[OperationContract]
[ServiceKnownType(typeof(Supervisor))]
List<Person> GetEmployee();

回答by Martin Staufcik

This exception means there is a serialization problem on the server side.

此异常意味着服务器端存在序列化问题。

This issue can be resolved by looking into the trace file (svclog). To turn tracing on use the following configuration:

可以通过查看跟踪文件 (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>

In my case I was serializing a value that was not in the enum.

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

回答by Rahbek

I had a lot of properties with no set{ } in it. Adding this solved my problem.

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

回答by Marcus Cunningham

Same problem but solved thanks to Wojciech's answer.

同样的问题,但由于Wojciech回答解决了

I had to do a bit more digging to find where to put the <security>tag so here is how the start of the system.serviceModel section looks now ...

我不得不做更多的挖掘才能找到放置<security>标签的位置,所以这里是 system.serviceModel 部分的开头现在的样子......

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

回答by Ben

I had this issue because I was using an older tutorial, and trying to configure programatically.

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

The part I was missing was to supply the metadata endpoint (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"
);