Ошибка в Mono System.Net.Socket или я что-то не так понимаю?(неверное количество отправленных байтов возвращено) - PullRequest
1 голос
/ 25 августа 2011

Проиграв некоторое время с Mono, я вижу одну странную вещь - каждый вызов Send (), EndSend (), SendAsync () и т. Д. Возвращает не количество байтов, отправленных в этой конкретной операции, а общее количество байтов, отправленных во времявремя жизни сокета.

Согласно различным источникам (включая официальную документацию Microsoft), количество отправленных байтов должно отражать только последнюю операцию (которая кажется логичной и стандартной), но в Mono это отличается.

Я пробовал Mono 2.8.2, 2.10.5 - это поведение все еще там.Просматривая источники (включая master на GitHub), я вижу, что это «поведение по замыслу», однако это противоречит документированному поведению.

Итак, мой вопрос - это ошибка в Mono, или ячто-то не так понял?Если это ошибка - как могло случиться, что она скрывается годами, и никто не заметил?

1 Ответ

3 голосов
/ 27 августа 2011

Извините, но не могу воспроизвести это с помощью 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

Что и ожидалось. Я тестировал Mono из git commit b21a860 в Ubuntu 10.10. Что касается 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, поэтому его не нужно обнулять - вы не можете дважды вызывать EndSend для одного и того же AsyncResult.).

EDIT:

Я только что протестировал его с асинхронной версией (т.е. EndSend), и он тоже работает правильно. Не могли бы вы опубликовать часть проблемного кода?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...