WCF streaming mode is apparently not streaming

I am trying to create a WCF streaming example for testing purposes only, and I cannot be sure that it is actually streaming.

The example is very simple:

  • The server returns large binary content (in this case, a PDF file)
  • The client writes a large binary file to the file.

However, the problem seems to be that although I believe I have correctly configured the server and client for streaming:

  • This is actually not streaming, because I'm in an IOException with the message The maximum message size quota for incoming messages (65536) has been exceeded
  • Reads in increments of 1536 bytes, even when I set my stream buffer to 8192 (or any other size)

The full host code is here:

 using System; using System.IO; using System.ServiceModel; using System.ServiceModel.Description; namespace WcfStreamingHost { internal class Program { private static void Main(string[] args) { BasicHttpBinding binding = new BasicHttpBinding(); binding.TransferMode = TransferMode.Streamed; binding.MaxBufferSize = 65536; binding.MaxReceivedMessageSize = 65536; binding.ReaderQuotas.MaxBytesPerRead = 65536; binding.SendTimeout = TimeSpan.FromMinutes(10); ServiceHost host = new ServiceHost(typeof (ContentProvider), new Uri("http://charles-m4600:1234/contentprovider")); host.Description.Behaviors.Add(new ServiceMetadataBehavior()); host.Description.Behaviors.Find<ServiceDebugBehavior>().IncludeExceptionDetailInFaults = true; host.AddServiceEndpoint(typeof (IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex"); host.AddServiceEndpoint(typeof (IContentProvider), binding, "streamed"); host.Open(); Console.ReadKey(); } } [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)] public class ContentProvider : IContentProvider { #region IContentProvider Members [OperationBehavior(AutoDisposeParameters = true)] public Stream GetFile() { Stream stream = File.OpenRead("large_file.pdf"); return stream; } #endregion } [ServiceContract] public interface IContentProvider { [OperationContract] Stream GetFile(); } } 

And the full client code is here:

 using System; using System.IO; using System.ServiceModel; using WcfStreamingClient.LocalSvc; namespace WcfStreamingClient { internal class Program { private static void Main(string[] args) { BasicHttpBinding binding = new BasicHttpBinding(); binding.TransferMode = TransferMode.Streamed; binding.MaxBufferSize = 65536; binding.MaxReceivedMessageSize = 65536; binding.ReaderQuotas.MaxBytesPerRead = 65536; binding.ReceiveTimeout = TimeSpan.FromMinutes(10); EndpointAddress address = new EndpointAddress("http://charles-m4600:1234/contentprovider/streamed"); using (ContentProviderClient client = new ContentProviderClient(binding, address)) { using (Stream stream = client.GetFile()) { FileInfo file = new FileInfo("output.pdf"); if (file.Exists) { file.Delete(); } using (FileStream fileStream = file.Create()) { const int bufferLen = 8192; byte[] buffer = new byte[bufferLen]; int count = 0; int total = 0; while ((count = stream.Read(buffer, 0, bufferLen)) > 0) { fileStream.Write(buffer, 0, count); total += count; Console.Out.WriteLine("Read {0} bytes", total); } } } } } } } 

I read several other posts on this issue, but cannot find any clues.

+4
source share
2 answers

Although your post was a long time ago, I came across it and thought that I would share my conclusions.

The maximum message size quota is always considered . Regardless of whether you have streaming translation or not. MSDN is very clear about this. The maximum buffer size can be optionally specified.

http://msdn.microsoft.com/en-us/library/ms731078%28v=vs.100%29.aspx

MaxReceivedMessageSize . The maximum size in bytes of the received message, including headers, before the transport raises an exception.

MaxBufferSize The maximum size in bytes of the buffer used for streaming data. If this transport quota is not set or the transport does not use streaming, then the quota value coincides with the lower quota value MaxReceivedMessageSize and MaxValue.

Why you always have chunks of 1536 bytes , I'm not quite sure. But I think this is because of the maximum size of the ethernet frame (except for jumbo frames):

http://en.wikipedia.org/wiki/Ethernet_frame

+3
source

MaxReceivedMessageSize is designed to prevent DOS attacks when connecting channels and managing MaxBufferSize messages on a channel. When the channel is configured to stream only the soap header, it is buffered and the body flows, the block size of the stream is controlled by the implementation of the service (8 Kb in your case), and maxrecievedmessagesize limits the size of the file + header. The maximum message size must be equal to the size of the MaxBufferSize file in buffered mode. But when streaming, MaxBufferSize should be small and MaxRecievedMessafeSize should be the expected file size. In streaming mode, MaxBufferSize can be used to prevent a DOS attack.

+1
source

All Articles