[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