Notice (2018-05-24): bugzilla.xamarin.com is now in
Please join us on
Visual Studio Developer Community and in the
Mono organizations on
GitHub to continue tracking issues. Bugzilla will remain
available for reference in read-only mode. We will continue to work
on open Bugzilla bugs, copy them to the new locations
as needed for follow-up, and add the new items under Related
Our sincere thanks to everyone who has contributed on this bug
tracker over the years. Thanks also for your understanding as we
make these adjustments and improvements for the future.
Please create a new report on
GitHub or Developer Community with
your current version information, steps to reproduce, and relevant error
messages or log files if you are hitting an issue that looks similar to
this resolved bug and you do not yet see a matching new report.
From the msdn documentation...
If you are using a connection-oriented protocol, Send will block until all of the bytes in the buffer are sent, unless a time-out was set by using Socket.SendTimeout. If the time-out value was exceeded, the Send call will throw a SocketException. In nonblocking mode, Send may complete successfully even if it sends less than the number of bytes in the buffer. It is your application's responsibility to keep track of the number of bytes sent and to retry the operation until the application sends the bytes in the buffer. There is also no guarantee that the data you send will appear on the network immediately. To increase network efficiency, the underlying system may delay transmission until a significant amount of outgoing data is collected. A successful completion of the Send method means that the underlying system has had room to buffer your data for a network send.
In Mono this isnt the behaviour observed (2.10.5 Fedora 16). I've had to use a construct like...
int amtSent = 0;
while (amtSent < _data.Length)
amtSent += conn.Send(_data.data, amtSent, _data.Length - amtSent, socketFlags.None);
To get around the early termination. The socket is in blocking mode and should block until all bytes are transmitted.
From your quote of the MSDN documentation: "Send may complete successfully
even if it sends less than the number of bytes in the buffer. It is your
application's responsibility to keep track of the number of bytes sent and to
retry the operation until the application sends the bytes in the buffer."
Read it closely. The sentence you quote as well is referring to a non-blocking send which isn't the case with the error I am reporting.
The first section is the relevant one. I quoted the entire paragraph so it wasn't out of context... The section you referenced when closing this *is* out of context and only applies to a non-blocking send.
"If you are using a connection-oriented protocol, Send will block until all of
the bytes in the buffer are sent, unless a time-out was set by using
There was no timeout set and its a blocking send. The bug report is valid and the current library behaviour is incorrect and breaks existing windows code.
The documented behavior with .NET (YMMV) is that the synchronous Send() might not send all the data BUT Begin/EndSend() guarantees that all the data will be sent.
The problem you are experiencing is due to different behavior of the TCP stack, including size of kernel buffers and such. Try your code on windows with a large buffer (2MB? 4MB?) and, if I recall correctly from testing this years ago, you will see how it won't send all the data.
MMm. Simple test blocks "forever" on Send() once the send buffer is filled up. Let me run my test on linux, may be on a Mac and then do the same thing but using Being/EndSend or SendAsync() and I'll report back.
Created attachment 1500 [details]
Test that works the same on linux and windows
The attached test behaves the same on windows and linux, i.e., it blocks once the send buffer is filled up. I don't see any partial reads or writes anywhere.
Could you provide a (similar) standalone test case that proves your point?
I'll need to work up a standalone test case. One factor... This code was threaded. A seperate reader and writer on the stream. The sender was doing blocking writes.
I'll get a test case together and post it as soon as possible.
This bug is critical for our service when we run it on Mono. Blocking sockets should not return from a send until the send is complete or failed, that is the behavior of non-blocking sockets. Failure to honor this behavior results in BeginSend not being safe to call multiple times with preserved ordering, because the first BeginSend will "complete" with less than N bytes sent, after which the second queued BeginSend will be handled. Standard behavior for BSD sockets on every platform I've written network code on is that send() will block until all the data has been sent in the default case of blocking sockets.
We have not received the requested information. If you are still experiencing this issue please provide all the requested information and reopen the bug report.