[Mono-dev] WCF NetTcpBinding doesn't seem to honor MaxReceivedMessageSize

matthieu Barthélemy bonsouere at gmail.com
Wed Aug 15 12:16:04 UTC 2012


Hi all,

My project uses WCF to perform remoting communications between a server and
a client.
Sometimes I have to transfer 'large' data (large meaning here "more than
the default max value").

So to get transferts to work, I had to declare my binding with the
following parameters:
var binding = new NetTcpBinding ();
binding.Security.Mode = SecurityMode.None;
 binding.OpenTimeout = new TimeSpan(1,0,0);
binding.SendTimeout = new TimeSpan(1,0,0);
 binding.CloseTimeout = new TimeSpan(1,0,0);
binding.MaxReceivedMessageSize = 1000000000;
 binding.MaxBufferPoolSize = 100000000;
var address = new EndpointAddress
("net.tcp://"+serverIP+":"+serverPort+"/");
 IRemoteOperations remote = new ChannelFactory<IRemoteOperations> (binding,
address).CreateChannel();
remote.CallMyMethodGeneratingBigData();


This works as expected on .NET/Windows, but under mono I get the following
exception:

Error : The message is too large.
  at
System.ServiceModel.Channels.NetTcp.TcpBinaryFrameManager.ReadSizedChunk ()
[0x00039] in
/usr/src/packages/BUILD/mono-2.10.9/mcs/class/System.ServiceModel/System.ServiceModel.Channels.NetTcp/TcpBinaryFrameManager.cs:202
  at
System.ServiceModel.Channels.NetTcp.TcpBinaryFrameManager.ReadSizedMessage
() [0x00089] in
/usr/src/packages/BUILD/mono-2.10.9/mcs/class/System.ServiceModel/System.ServiceModel.Channels.NetTcp/TcpBinaryFrameManager.cs:337
  at System.ServiceModel.Channels.NetTcp.TcpDuplexSessionChannel.TryReceive
(TimeSpan timeout, System.ServiceModel.Channels.Message& message) [0x00046]
in
/usr/src/packages/BUILD/mono-2.10.9/mcs/class/System.ServiceModel/System.ServiceModel.Channels.NetTcp/TcpDuplexSessionChannel.cs:171
  at System.ServiceModel.Channels.DuplexChannelBase.Receive (TimeSpan
timeout) [0x00000] in
/usr/src/packages/BUILD/mono-2.10.9/mcs/class/System.ServiceModel/System.ServiceModel.Channels/DuplexChannelBase.cs:178
  at
System.ServiceModel.MonoInternal.ClientRuntimeChannel.RequestCorrelated
(System.ServiceModel.Channels.Message msg, TimeSpan timeout, IOutputChannel
channel) [0x00013] in
/usr/src/packages/BUILD/mono-2.10.9/mcs/class/System.ServiceModel/System.ServiceModel/ClientRuntimeChannel.cs:594
  at System.ServiceModel.MonoInternal.ClientRuntimeChannel.Request
(System.ServiceModel.Channels.Message msg, TimeSpan timeout) [0x00019] in
/usr/src/packages/BUILD/mono-2.10.9/mcs/class/System.ServiceModel/System.ServiceModel/ClientRuntimeChannel.cs:584
  at System.ServiceModel.MonoInternal.ClientRuntimeChannel.Request
(System.ServiceModel.Description.OperationDescription od, System.Object[]
parameters) [0x00066] in
/usr/src/packages/BUILD/mono-2.10.9/mcs/class/System.ServiceModel/System.ServiceModel/ClientRuntimeChannel.cs:537
  at System.ServiceModel.MonoInternal.ClientRuntimeChannel.DoProcess
(System.Reflection.MethodBase method, System.String operationName,
System.Object[] parameters) [0x00038] in
/usr/src/packages/BUILD/mono-2.10.9/mcs/class/System.ServiceModel/System.ServiceModel/ClientRuntimeChannel.cs:502
  at System.ServiceModel.MonoInternal.ClientRuntimeChannel.Process
(System.Reflection.MethodBase method, System.String operationName,
System.Object[] parameters) [0x0001c] in
/usr/src/packages/BUILD/mono-2.10.9/mcs/class/System.ServiceModel/System.ServiceModel/ClientRuntimeChannel.cs:479


My mono source code skill are not (yet) good enough to dive very deep, but
it looks like the "binding.MaxReceivedMessageSize" custom value is not
honored.
Greping the sources (from mono 2.10.8 tarball), I realized that the
file mcs/class/System.ServiceModel/System.ServiceModel.Channels.NetTcp/TcpBinaryFrameManager.cs
has the following code (in my opinion, part of the problem is located line
201):

193                 public byte [] ReadSizedChunk ()
194                 {
195                         lock (read_lock) {
196
197                         int length = reader.ReadVariableInt ();
198                         if (length == 0)
199                                 return empty_bytes;
200
201                         if (length > 65536)
202                                 throw new InvalidOperationException
("The message is too large.");
203
204                         byte [] buffer = new byte [length];
205                         for (int readSize = 0; readSize < length; )
206                                 readSize += reader.Read (buffer,
readSize, length - readSize);
207                         return buffer;
208
209                         }
210                 }


if I replace this 64k hard-coded value (in my case, to be 10x bigger) and
recompile my mono instance, everything works as expected.

I guess there was a good reason to put an hardcoded value here, but then,
what is supposed to happen for messages bigger than this value,
when MaxReceivedMessageSize has been set appropriately?
Should mono have a loop calling ReadSizedChunk to process chunks until we
reach final size (reader.ReadVariableInt ())?
Or should the hardcoded 65536 be removed?

Many thanks for your help!

My version of Mono:
> mono -V
Mono JIT compiler version 2.10.9 (tarball Fri Jul 13 23:11:26 UTC 2012)
Copyright (C) 2002-2011 Novell, Inc, Xamarin, Inc and Contributors.
www.mono-project.com
        TLS:           __thread
        SIGSEGV:       altstack
        Notifications: epoll
        Architecture:  amd64
        Disabled:      none
        Misc:          debugger softdebug
        LLVM:          supported, not enabled.
        GC:            Included Boehm (with typed GC and Parallel Mark)



Matthieu Barthelemy
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ximian.com/pipermail/mono-devel-list/attachments/20120815/b65377e4/attachment.html>


More information about the Mono-devel-list mailing list