Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WCF NamedPipe CommunicationException-“名称”;管子已经断了。(109,0x6d)。”;_C#_Wcf_Windows Services_Named Pipes - Fatal编程技术网

C# WCF NamedPipe CommunicationException-“名称”;管子已经断了。(109,0x6d)。”;

C# WCF NamedPipe CommunicationException-“名称”;管子已经断了。(109,0x6d)。”;,c#,wcf,windows-services,named-pipes,C#,Wcf,Windows Services,Named Pipes,我正在编写一个带有“状态工具”的Windows服务。该服务承载一个名为管道端点的WCF,用于进程间通信。通过命名管道,状态工具可以定期查询服务的最新“状态” 在我的开发机器上,我有多个IP地址;其中之一是具有192.168.1.XX地址的“本地”网络。另一个是“公司”网络,地址为10.0.X.XX。Windows服务在单个IP地址上收集UDP多播通信 到目前为止,只要使用“192.168.1.XX”地址,Windows服务就可以正常工作。它始终向客户正确报告状态 当我切换到另一个“公司”IP地

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

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

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

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

"There was an error reading from the pipe: The pipe has been ended. (109, 0x6d)."
现在,我不认为UDP客户端的“声明”IP地址与命名管道接口的功能有任何关系;它们是应用程序中完全独立的部分

以下是相关的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();
//在客户端应用程序上:
string myNamedPipe=“net。pipe://127.0.0.1/MyNamedPipe";
通道工厂代理工厂=
新渠道工厂(
新建NetNamedPipeBinding(),
新端点地址(myNamedPipe));
//在Windows服务上:
string myNamedPipe=“net。pipe://127.0.0.1/MyNamedPipe";
myService=newmyservice(myCustomArgs);
serviceContractHost=新的ServiceHost(myService);
serviceContractHost.AddServiceEndpoint(
类型(IMyService),
新建NetNamedPipeBinding(),
myNamedPipe);
serviceContractHost.Open();

我不认为这是一个“权限”问题——我正在以管理权限运行客户端——但这可能是某些特定于域的原因造成的?

事实证明,IP地址完全是一个骗局

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

我的枚举定义如下:

[DataContract]
public enum MyEnumValues : Byte
{
    [EnumMember]
    Enum1 = 0x10,
    [EnumMember]
    Enum2 = 0x20,
    [EnumMember]
    Enum3 = 0x30,
    [EnumMember]
    Enum4 = 0x40,
} 
表面看起来不错

但是基础服务报告的原始状态是字节值“0”,并且没有相应的枚举值来强制转换它

一旦我确保枚举值都是有效的,工具就会像圣诞树一样亮起来


当有疑问时,假设您的WCF数据无效。

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

也有相同的问题
从管道读取时出错:无法识别的错误109(0x6d)。

  • 一个原因是客户端和服务器之间的绑定不一致(无通信)
  • 另一个间歇性问题与超时有关
两者都有相同的顶部错误消息

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

设置得太低的绑定超时:

sendTimeout="00:00:05" receiveTimeout="00:00:05"
堆栈跟踪:

位于System.ServiceModel.Channels.StreamConnection.Read(字节[]缓冲区、Int32偏移量、Int32大小、TimeSpan超时)
位于System.ServiceModel.Channels.SessionConnectionReader.Receive(TimeSpan超时)
位于System.ServiceModel.Channels.SynchronizedMessageSource.Receive(TimeSpan超时)
位于System.ServiceModel.Channels.TransportDuplexSessionChannel.Receive(TimeSpan超时)
在System.ServiceModel.Channels.TransportDuplexSessionChannel.TryReceive(TimeSpan超时、消息和消息)
位于System.ServiceModel.Dispatcher.DuplexChannelBinder.Request(消息消息,TimeSpan超时)
在System.ServiceModel.Channels.ServiceChannel.Call(字符串操作、布尔单向、ProxyOperationRuntime操作、对象[]输入、对象[]输出、时间跨度超时)
在System.ServiceModel.Channels.ServiceChannel.Call(字符串操作、布尔单向、ProxyOperationRuntime操作、对象[]输入、对象[]输出)
位于System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage方法调用,ProxyOperationRuntime操作)

在System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage消息)

中,当返回的负载太大时,我的WCF服务中发生了这种情况。通过将其添加到app.config中的serviceBehavior中修复:

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

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

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

[OperationContract]
[ServiceKnownType(typeof(Supervisor))]
List<Person> GetEmployee();
[运营合同]
[ServiceKnownType(类型(主管))]
列出GetEmployee();

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

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


在我的例子中,我序列化了一个不在枚举中的值。

我有很多属性,其中没有集合{}。加上这个解决了我的问题

同样的问题,但由于的解决

<system.serviceModel>
   <bindings>
     <netNamedPipeBinding>
       <binding>
         <security mode="None"></security>
       </binding>
     </netNamedPipeBinding>
   </bindings>
   ....
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"
);
<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