Bug in Mono System.Net.Socket or I misunderstand something? (incorrect number of bytes sent returned)
After playing a while with Mono, I see one strange thing - every call to Send(), EndSend(), SendAsync() etc return not number of bytes sent in this particular operation, but total number of bytes sent during the lifetime of a Socket.
According to various sources (including official Microsoft documentation), the number of bytes sent should reflect only last operation (which seems logical and standard), b开发者_如何转开发ut in Mono this is different.
I've tried Mono 2.8.2, 2.10.5 - this behaviour is still there. Looking into sources (including master on GitHub), I see that this is "behaviour by design", however, this contradicts to documented behaviour.
So, my question is - is this a bug in Mono, or I misunderstood something? If this is a bug - how could it happen that it lurks there for years, and nobody noticed?
Sorry, but can't reproduce that with Send or EndSend. Considering test program and Mono's source code I would say there is no bug in Mono. Details below.
I used this code to test, it is not beautiful, however shows what should be shown:
using System;
using System.Net.Sockets;
using System.Net;
using System.Threading;
namespace Test2
{
class MainClass
{
public static void Main (string[] args)
{
var t = new Thread(Read) { IsBackground = true };
t.Start();
Thread.Sleep(300);
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(new IPEndPoint(IPAddress.Loopback, 1234));
for(var i = 0; i < 10; i++)
{
Console.WriteLine(socket.Send(new [] {(byte) 0x12}));
}
}
public static void Read()
{
var s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
s.Bind(new IPEndPoint(IPAddress.Loopback, 1234));
s.Listen(1);
var accepted = s.Accept();
while(true)
{
accepted.Receive(new byte[1]);
}
}
}
}
On my machine output is:
1
1
1
1
1
1
1
1
1
1
Which is what expected. I was testing using Mono from git commit b21a860 on Ubuntu 10.10. About send_so_far
, you mentioned: please notice, that call to int Send (byte [] buf)
calls internal int Send_nochecks(...)
and this in turn calls int Send_internal (socket, buf, offset, size, flags, out nativeError)
which is tagged with [MethodImplAttribute (MethodImplOptions.InternalCall)]
(so implemented directly in runtime) and uses no send_so_far
at all. (As far as I can see, send_so_far
is used in AsyncResult, but only in one AsyncResult, therefore it does not have to be zeroed - you can't call EndSend twice on same AsyncResult.).
EDIT:
I have just tested it with async version (i.e. EndSend) and it works properly too. Could you post some piece of problematic code?
精彩评论