16

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."

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.

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.

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:

"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!

Here are the relevant WCF config sections:

//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?

BTownTKD
  • 7,911
  • 2
  • 31
  • 47
  • What does the exception stack trace look like? Are you *sure* nothing else changed? Did you restart the Status Tool after switching the service configuration? Could you post the part of your Status Tool code which instantiates your rpoxy and makes the WCF call? – Chris Dickson Apr 06 '13 at 17:10
  • I will update the question on Monday, when I get back to work. A friend also suggested that the IP Address may be a red herring, and the real difference may be the return value of particular Enums. I will investigate that as well. – BTownTKD Apr 06 '13 at 18:08

10 Answers10

15

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

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

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.

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

When in doubt, assume your WCF data is invalid.

BTownTKD
  • 7,911
  • 2
  • 31
  • 47
  • Was there anything in the tracing files that pointed to this or are we stuck with a generic "pipe has been ended" error and need to scan all the code involved to hopefully find the potential serialization issue? – Nelson Rothermel Mar 14 '14 at 00:51
  • 3
    I had to scan all the data and manually verify it. I hope you have better luck with helpful traces! – BTownTKD Mar 14 '14 at 12:59
  • "When in doubt, assume your WCF data is invalid." - saved my day :) – Yaniv Jul 22 '17 at 12:53
  • I got the same error by forgetting to put the [EnumMember] prefix on each enum value. – gotorg Feb 07 '19 at 00:08
5

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:

<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.

riQQ
  • 9,878
  • 7
  • 49
  • 66
Martin Staufcik
  • 8,295
  • 4
  • 44
  • 63
4

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:

[OperationContract]
[ServiceKnownType(typeof(Supervisor))]
List<Person> GetEmployee();
Ali Fattahian
  • 495
  • 1
  • 6
  • 24
3

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

  • One reason was inconsistent binding between client and server <netNamedPipeBinding> <security mode="None"></security>... (no communication)
  • The other intermittent issue was time-out related.

Both had the same top error message.

Increasing the time out in 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)

Wojciech
  • 199
  • 9
2

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

<dataContractSerializer maxItemsInObjectGraph="[some big number]" />
pizza247
  • 70
  • 1
  • 6
1

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.

J S
  • 901
  • 8
  • 15
1

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

Rahbek
  • 1,331
  • 14
  • 9
0

Same problem but solved thanks to Wojciech's answer.

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 ...

<system.serviceModel>
   <bindings>
     <netNamedPipeBinding>
       <binding>
         <security mode="None"></security>
       </binding>
     </netNamedPipeBinding>
   </bindings>
   ....
Community
  • 1
  • 1
0

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"
);
Ben
  • 54,723
  • 49
  • 178
  • 224
0

To add to the mix, our code was serializing a Dictionary<string, List<int>>. This seemed to cause problems. Marking the class with a [DataContract] and each public property to be serialized (including the Dictionary) resolved this issue for us.

<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
James Westgate
  • 11,306
  • 8
  • 61
  • 68