48 попугаев при опросе

Просмотр 13 сообщений - с 16 по 28 (из 28 всего)
  • Автор
    Сообщения
  • #22327
    Romiros
    Участник

    Нужно поставить галочку отображать процессы всех пользователей, чтобы увидеть ScadaComm

    #22328
    manjey73
    Участник

    Переделал на остановку по байту без создания своего класса

     private void ReadAfterHeader(int needCnt, byte[] buffer, byte lastByte, out int readCnt, out string logText)
            {
                bool stopReceived = false;
                bool checkWhile;
                readCnt = 0;
                int offset = 5;
                Connection.BinStopCondition binStop = new Connection.BinStopCondition(0xC0);
    
                do
                {
                    checkWhile = true;
                    int readCnt1 = Connection.Read(buffer, offset, needCnt, ReqParams.Timeout, binStop,  out stopReceived);
    
                    if (stopReceived)
                    {
                        offset = offset + readCnt1;
                        needCnt = offset - 1;
                    }
                    else checkWhile = false;
    
                    readCnt += readCnt1;
                }
                while (checkWhile);
    
                logText = Connection.BuildReadLogText(buffer, 5, readCnt, CommUtils.ProtocolLogFormats.Hex);
            }

    Так же, из буфера пропадает байт каждую сессию…
    Интересно, кто его съедает ?

    #22329
    manjey73
    Участник

    Нашел причину этой ошибки 🙂

    Для обработки после чтения ответов с наличием маркера (его необходимо удалять потом) я использовал комбинацию

    List<byte> inbufList = inBuf.ToList(); и потом

    inBuf = inbufList.ToArray(); так вот последнее не копирует в byte[] список байтов а создает его по новому, а так как я логикой удаляю маркер из буфера ответа, то соответственно он уменьшается на количество найденных маркеров….

    Вот она, где собака скрылась 🙂

    #22334
    Mikhail
    Модератор

    Хорошо, что нашли.
    ToList и ToArray создают новые объекты, выделяя под них память. Поэтому нужно избегать их вызова при каждом опросе.
    Для копирования массивов есть другие функции, если понадобятся.

    #22338
    manjey73
    Участник

    Ага, есть — myList.CopyTo(inBuf) 🙂 уже заменил на такой вариант.
    Просто думал, что в уже объявленный массив будет именно копирование, а не создание нового, но оказалось что это не так.

    А вот копирования byte[] в List нет, хотя так же просится…

    • Этот ответ был изменен 2 года, 1 месяц назад от manjey73.
    #22365
    Mikhail
    Модератор

    А вот копирования byte[] в List нет, хотя так же просится

    Навскидку не помню такого метода. Обычно такая операция не нужна.

    #22372
    manjey73
    Участник

    Предлагаете вести поиск по byte[] циклом? когда куда быстрее найти и удалить в List<byte>, не просто изменить значение, а именно удалить ячейку с данным значением…

    #22403
    Mikhail
    Модератор

    Можно ли обойтись без удаления элемента?
    При удалении в списке все значения справа копируются на предыдущее место. Для больших списков не оптимально. Конечно современное железо потянет, но не очень красиво.

    #22406
    manjey73
    Участник

    Нет, без удаления нельзя.
    Суть, значения 0xC0, 0xC1, 0xC2 подменяются на пары 0xC0 0x00, 0xC0 0x01, 0xC0 0x02

    Если делать на лету, то после остановки по 0xC0 нужно сперва считать следующий байт на предыдущее место с прибавлением к нему 0xC0 и потом продолжить опрос по Connection.Read так же с проверкой на 0xC0.

    Проще в цикле запускать Connection.Read столько раз, сколько он остановится по 0xC0 и потом один раз пройтись по буферу.

    Хотя и не знаю, может действительно сделать код для Connection.Read но я еще исходил из соображений, чтобы было видно, что в блоках данных есть указанные пары. С другой стороны их и так будет видно, наличие 0xC0, 0xC1, 0xC2 в ответе…

    Какой путь более оптимален с вашей точки зрения, реализовать в Connection.Read или в случае появления таких маркеров подменить через реализацию списка или циклом по byte[] массиву в новый с копированием? В самом последнем варианте можно так же заранее задать массив.

    #22407
    manjey73
    Участник

    Опять же, если я объявлю List<byte> заранее, а потом начну из него удалять ячейки, то приду к тому же, к уменьшению списка.

    Фокус в том, что CRC рассчитывается по байтам 0xC0, 0xC1 или 0xC2 а не заменяющим парам.

    Таких пЕсателей протоколов к стенке бы ставил 🙂

    • Этот ответ был изменен 2 года, 1 месяц назад от manjey73.
    #22433
    Mikhail
    Модератор

    > Таких пЕсателей протоколов к стенке бы ставил
    Они сами не пишут драйвера под свои протоколы.

    Если без удаления нельзя, то я бы заранее создал отдельный буфер и в него копировал данные из 1-го буфера, пропуская ненужные байты. Дело вкуса.

    #22446
    manjey73
    Участник

    Да просто байтов масок может оказаться две, например в счетчике точно.
    То есть чтобы не давать работать мусоросборщику копирование оптимальный вариант.
    Надо будет попробовать в коде как это сделать более оптимальнее.
    Например скопировать все, а потом найдя индекс (тут незадача, есть метод поиска индекса определенного значения в byte[] ?) и далее копировать по одному байту смещая и выкидывая лишнее.

    #22515
    Mikhail
    Модератор

    есть метод поиска индекса определенного значения в byte[] ?

    Метод поиска индекса значения в массиве методом перебора, вероятно есть. Ну или самому написать.

Просмотр 13 сообщений - с 16 по 28 (из 28 всего)
  • Вы должны авторизироваться для ответа в этой теме.