Bug在Mono System.Net.Socket或我误解了什么?(发送返回的字节数不正确)

本文关键字:返回 不正确 字节数 什么 System Mono Net Socket 误解 Bug | 更新日期: 2023-09-27 18:06:50

在使用Mono玩了一段时间后,我看到了一件奇怪的事情-每次调用Send(), EndSend(), SendAsync()等返回的不是在此特定操作中发送的字节数,而是在Socket生命周期内发送的字节总数。

根据各种来源(包括微软官方文档),发送的字节数应该只反映最后一个操作(这似乎是合乎逻辑和标准的),但在Mono中这是不同的。

我试过Mono 2.8.2, 2.10.5 -这种行为仍然存在。查看源代码(包括GitHub上的master),我看到这是"设计行为",然而,这与记录的行为相矛盾。

所以,我的问题是-这是一个bug在Mono,还是我误解了什么?如果这是一个bug,它怎么会在那里潜伏了很多年而没有人注意到呢?

Bug在Mono System.Net.Socket或我误解了什么?(发送返回的字节数不正确)

对不起,但是不能用Send或EndSend复制。考虑到测试程序和Mono的源代码,我想说Mono没有bug。下面的细节。

我用这段代码来测试,它并不漂亮,但是显示了应该显示的内容:

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两次。)

编辑:

我刚刚用async版本(即EndSend)测试了它,它也能正常工作。你能发布一些有问题的代码吗?