在与Mono玩了一段时间之后,我看到一个奇怪的事情 - 每次调用Send(),EndSend(),SendAsync()等都不会返回此特定操作中发送的字节数,但是在此期间发送的总字节数套接字的生命周期。
根据各种来源(包括官方的Microsoft文档),发送的字节数应仅反映最后一次操作(看似逻辑和标准),但在Mono中这是不同的。
我尝试过Mono 2.8.2,2.10.5 - 这种行为仍然存在。查看源代码(包括GitHub上的master),我发现这是“按设计行为”,但这与记录的行为相矛盾。
所以,我的问题是 - 这是Mono中的一个错误,还是我误解了一些东西?如果这是一个错误 - 它怎么可能发生在那里潜伏多年,没有人注意到?
答案 0 :(得分:3)
抱歉,但无法使用Send或EndSend重现该内容。考虑到测试程序和Mono的源代码,我会说Mono中没有错误。详情如下。
我用这段代码进行测试,它并不漂亮,但显示了应该显示的内容:
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]);
}
}
}
}
我的机器输出是:
1
1
1
1
1
1
1
1
1
1
这是预期的。我在Ubuntu 10.10上使用git commit b21a860中的Mono进行测试。关于send_so_far
,您提到:请注意,拨打int Send (byte [] buf)
来电internal int Send_nochecks(...)
,并依次拨打int Send_internal (socket, buf, offset, size, flags, out nativeError)
[MethodImplAttribute (MethodImplOptions.InternalCall)]
标记{直接实施在运行时)并且根本不使用send_so_far
。 (据我所知,send_so_far
在AsyncResult中使用,但只在一个AsyncResult中使用,因此不必将其归零 - 您不能在相同的AsyncResult上调用两次EndSend。)。
修改强>
我刚刚使用异步版本(即EndSend)对其进行了测试,它也能正常工作。你能发一些有问题的代码吗?