Winpcap в приложении
От: milkpot Россия  
Дата: 15.03.19 16:17
Оценка:
Устройство подключается к ПК с помощью сетевого кабеля.Интерфейс Gigabit Ethernet
Устройство принимает/получает пакеты размером 86 байт (включая MAC заголовок).
Структура пакета: MAC адрес приёмника, MAC адрес источника, два байта — длина сообщения (всегда 72 байта).
Затем идет 8 байтовый заголовок и 64 байта данных.
Из устройства в ПК идут широковещательные пакеты.
Одна из команд реализованных в устройстве — передача в ПК изображения 640x480, разбитового на пакеты.
64 байта данных в пакете содержат фрагмент изображения.

Приложение использует Winpcap интерфейс.
Полностью принять все пакеты не получается. Изображение принимается не полностью.
Передача пакетов останавливается по какой-то причине.
Возможно, что объем ОЗУ ПК тоже влияет на работу приложения. Может быть, что размер пакета должен быть
больше для передачи в ПК изображения.
На данный момент устройство посылает в ПК пакеты на скорости в 64 раза медленнее скорости Gigabit Ethernet.
Задача максимум стоит: посылать пакеты на скорости Gigabit Ethernet.
Re: Winpcap в приложении
От: -prus-  
Дата: 15.03.19 16:44
Оценка:
Здравствуйте, milkpot, Вы писали:

M>Устройство подключается к ПК с помощью сетевого кабеля.Интерфейс Gigabit Ethernet

M>Устройство принимает/получает пакеты размером 86 байт (включая MAC заголовок).
M>Структура пакета: MAC адрес приёмника, MAC адрес источника, два байта — длина сообщения (всегда 72 байта).
M>Затем идет 8 байтовый заголовок и 64 байта данных.

Судя по всему, устройство общается по Ethernet, внутри которого свой формат данных.
Не MAC заголовок только, а Ethernet, наверное... Он 14 байт. Два MAC адреса по 6 байт (итого 12 байт) + 2 байта EtherType. Если ты про 2 байта, которые за MAC адресами, то это как раз EtherType, а не длина сообщения, скорее всего.

M>Приложение использует Winpcap интерфейс.

M>Полностью принять все пакеты не получается. Изображение принимается не полностью.

Код можешь показать? Хотя бы захвата пакетов и дальнейшего их парсинга
С уважением,
Евгений
Re: Winpcap в приложении
От: Слава  
Дата: 15.03.19 16:47
Оценка: -1
Здравствуйте, milkpot, Вы писали:

M>Устройство подключается к ПК с помощью сетевого кабеля.Интерфейс Gigabit Ethernet

M>Устройство принимает/получает пакеты размером 86 байт (включая MAC заголовок).
M>Структура пакета: MAC адрес приёмника, MAC адрес источника, два байта — длина сообщения (всегда 72 байта).
M>Затем идет 8 байтовый заголовок и 64 байта данных.
M>Из устройства в ПК идут широковещательные пакеты.

Оторвать руки железнячнику*, сделавшему устройство, и отправить учить computer science. После чего реализовать в устройстве буфер для пакетов и стек tcp/ip. И работать, как люди работают, а не с выдумкой, и одним топором, и без единого гвоздя.

M>Полностью принять все пакеты не получается. Изображение принимается не полностью.


Для надёжной сетевой передачи нужны повторы, подтверждения и прочее. Судя по описанию, в протоколе их в принципе нет, потому что писал его паяльник*.

*паяло — то, чем паяют, паяльник — тот, кто паяет, железнячник
Re: Winpcap в приложении
От: Pzz Россия https://github.com/alexpevzner
Дата: 15.03.19 19:18
Оценка:
Здравствуйте, milkpot, Вы писали:

M>Приложение использует Winpcap интерфейс.

M>Полностью принять все пакеты не получается. Изображение принимается не полностью.
M>Передача пакетов останавливается по какой-то причине.

Останавливается, или часть пакетов случайным образом теряется?

M>Возможно, что объем ОЗУ ПК тоже влияет на работу приложения. Может быть, что размер пакета должен быть

M>больше для передачи в ПК изображения.
M>На данный момент устройство посылает в ПК пакеты на скорости в 64 раза медленнее скорости Gigabit Ethernet.
M>Задача максимум стоит: посылать пакеты на скорости Gigabit Ethernet.

В твоем письме слишком мало данных, чтобы поставить какой-то диагноз. Например, можно предположить, что программа внутри устройства написана с ошибкой, и просто "забывает" прислать часть пакетов.

Но вообще, этот ваш дизайн не полетит. Во-первых, чтобы получить скорость, сравнимую со скоростью ethernet'а, надо слать большие пакеты, а не маленькие. Во-вторых, нужен какой-то flow control. В третьих, должна быть защита от потери пакетов. А потеря пакетов может происходить даже, если все остальное сделано хорошо (правда, в нормальных условиях их должно тетяться совсем немного).

А зачем работать на уровне голого Ethernet'а? Я понимаю, что TCP не во всякое устройство запишнешь, но UDP сделать совсем несложно, и сразу появляется возможность работать на уровне простых советских сокетов, а не через winpcap, к которому надо еще и драйвер ставить.
Re[2]: Winpcap в приложении
От: Pzz Россия https://github.com/alexpevzner
Дата: 15.03.19 19:30
Оценка:
Здравствуйте, Слава, Вы писали:

С>Оторвать руки железнячнику*, сделавшему устройство, и отправить учить computer science. После чего реализовать в устройстве буфер для пакетов и стек tcp/ip. И работать, как люди работают, а не с выдумкой, и одним топором, и без единого гвоздя.


Я как-то работал в проекте, в котором надо было написать фирмварий к сложному и замысловатому чипу, сделанному в нашей же конторе. В процессе написания драйвера для ethernet-контроллера выяснилось, что есть 3 размера пакетов, которые эта глючная железка отказывается принимать. Что-то вроде 137, 138 и 139 байт. Выяснилось совершенно случайно, я при отладке драйвера сказал ping чего-то-там, и вот DNS-ответ на это "чего-то-там" имело как раз "правильный" размер, из-за чего имя не резолвилось (а все остальное к этому времени уже более-менее работало).

Как ты думаешь, кто-нибудь оторвал руки железячнику? А вот и нет, мы, программисты, встали на уши и нашли способ обойти эту проблему в софтварии. Потому что переделать чип стоит $300K и занимает не один месяц, а неделя работы программиста столько не стоит и столько не занимает.

И это всегда делается так в программно-аппаратных проектах. Когда ты в каком-нибудь из них поучаствуешь, то сам узнаешь

Ну я уж не говорю о том, что не для всякой железки есть готовый стек tcp/ip, и далеко не во всякой конторе наидутся люди, способные его написать.
Re[3]: Winpcap в приложении
От: Слава  
Дата: 15.03.19 20:44
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Как ты думаешь, кто-нибудь оторвал руки железячнику? А вот и нет, мы, программисты, встали на уши и нашли способ обойти эту проблему в софтварии. Потому что переделать чип стоит $300K и занимает не один месяц, а неделя работы программиста столько не стоит и столько не занимает.


Это безобразие. Так мы никакого светлого будущего со всеобщей роботизацией не построим. За подобные недочёты хорошо бы карать поставщика.

Pzz>И это всегда делается так в программно-аппаратных проектах. Когда ты в каком-нибудь из них поучаствуешь, то сам узнаешь


Я участвовал. Принимал по сети трёхбайтовый float. "Пусть найдет тебе Федот Hе диковину какую — Двухдюймовый дисковод!"

Pzz>Ну я уж не говорю о том, что не для всякой железки есть готовый стек tcp/ip, и далеко не во всякой конторе наидутся люди, способные его написать.


Есть же несколько свободных стеков, миниатюрных и под лицензией BSD.
Re[2]: Winpcap в приложении
От: milkpot Россия  
Дата: 18.03.19 10:08
Оценка:
Здравствуйте, Pzz, Вы писали:

M>>Передача пакетов останавливается по какой-то причине.


Pzz>Останавливается, или часть пакетов случайным образом теряется?


Передача пакетов останавливается. Количество полученных пакетов каждый раз разное. Передача останавливается на уровне 2800-3400 пакетов.
Если ОС только запущена( не из спящего режима), то удается получить 4300-4500 пакетов.
Максимальное количество пакетов, которые надо получить — 4800 шт.
Вот изображение которое получается после приема пакетов.

Вертикальные полосы присутствуют в каждом полученном изображении.

M>>Возможно, что объем ОЗУ ПК тоже влияет на работу приложения. Может быть, что размер пакета должен быть

M>>больше для передачи в ПК изображения.
M>>На данный момент устройство посылает в ПК пакеты на скорости в 64 раза медленнее скорости Gigabit Ethernet.
M>>Задача максимум стоит: посылать пакеты на скорости Gigabit Ethernet.

Pzz>В твоем письме слишком мало данных, чтобы поставить какой-то диагноз. Например, можно предположить, что программа внутри устройства написана с ошибкой, и просто "забывает" прислать часть пакетов.


Pzz>Но вообще, этот ваш дизайн не полетит. Во-первых, чтобы получить скорость, сравнимую со скоростью ethernet'а, надо слать большие пакеты, а не маленькие. Во-вторых, нужен какой-то flow control. В третьих, должна быть защита от потери пакетов. А потеря пакетов может происходить даже, если все остальное сделано хорошо (правда, в нормальных условиях их должно тетяться совсем немного).


Можно вкратце рассказать о flow control и защите от потери пакетов.

Pzz>А зачем работать на уровне голого Ethernet'а? Я понимаю, что TCP не во всякое устройство запишнешь, но UDP сделать совсем несложно, и сразу появляется возможность работать на уровне простых советских сокетов, а не через winpcap, к которому надо еще и драйвер ставить.

Логика устройства реализована в ПЛИС. Не могу сказать насколько трудоемко реализовать UDP.
Re[2]: Winpcap в приложении
От: milkpot Россия  
Дата: 18.03.19 10:16
Оценка:
Здравствуйте, -prus-, Вы писали:

P>Здравствуйте, milkpot, Вы писали:


M>>Устройство подключается к ПК с помощью сетевого кабеля.Интерфейс Gigabit Ethernet

M>>Устройство принимает/получает пакеты размером 86 байт (включая MAC заголовок).
M>>Структура пакета: MAC адрес приёмника, MAC адрес источника, два байта — длина сообщения (всегда 72 байта).
M>>Затем идет 8 байтовый заголовок и 64 байта данных.

P>Судя по всему, устройство общается по Ethernet, внутри которого свой формат данных.

P>Не MAC заголовок только, а Ethernet, наверное... Он 14 байт. Два MAC адреса по 6 байт (итого 12 байт) + 2 байта EtherType. Если ты про 2 байта, которые за MAC адресами, то это как раз EtherType, а не длина сообщения, скорее всего.

M>>Приложение использует Winpcap интерфейс.

M>>Полностью принять все пакеты не получается. Изображение принимается не полностью.

P>Код можешь показать? Хотя бы захвата пакетов и дальнейшего их парсинга

Вот фрагмент кода.
// Globals
BYTE imageArray[307200/*640*480*/]={0}; 
int ArraySize=307200;
int ArrayCounter=0;

// Locals
int i1;
int loc_counter=0;

    if(pcap_datalink(adhandle) != DLT_EN10MB)
    {
        fprintf(stderr,"\nThis program works only on Ethernet networks.\n");
        /* Free the device list */
       // pcap_freealldevs(alldevs);
        return ;
    }    

while((res = pcap_next_ex( adhandle, &header, &pkt_data)) >= 0){;
        
        if(res == 0)
            /* Timeout elapsed */
            continue;
        i=0;i1=header->len;
        
        ;// Выбор пакета по MAC адресу
        if( pkt_data[6]==0x22 && pkt_data[7]==0x11 && pkt_data[8]==0x11 &&
            pkt_data[9]==0x11 && pkt_data[10]==0x11 && pkt_data[11]==0x11
            ) {
        //
        pointer_to_dialog->buf_Str.Format(_T("len:%d (%d)"), header->len, loc_counter);
        //pointer_to_dialog->buf_Str.Format(_T("%s,%.6d len:%d (%d)"), timestr_T, header->ts.tv_usec, header->len, loc_counter);
        // Печать в GUI ListBox
        toOtherThreadList_withTimeout(pointer_to_dialog->my_list.GetSafeHwnd(),pointer_to_dialog->buf_Str);
        loc_counter++;
        //
        switch(::InterlockedExchangeAdd((PLONG) & ::v_operation_value,0) /* reads ::v_operation_value */)
        {
            case 1:
                {
                } break;
            case 4:// Получение изображения
                {   //        14+8
                    for(int i=22;i<i1;i++)
                    {
                        ::imageArray[::ArrayCounter]=pkt_data[i];
                        ::ArrayCounter++;
                    }
                    //memcpy(&::imageArray[::ArrayCounter],&pkt_data[22],64);
                    //::ArrayCounter+=64I32;
                    if(::ArrayCounter==::ArraySize)
                    {
                        ::ArrayCounter=0;
                        loc_counter=0;
                        // Печать в GUI ListBox
                        toOtherThreadList_withTimeout(pointer_to_dialog->my_list.GetSafeHwnd(),_T(" Кадр принят"));
                        //::InterlockedExchange( (long *) & ::act_done , 2L );
                        ::InterlockedExchange( (long *) & ::v_operation_value, 0 );
                        //::SetEvent(::eventlockingHandle_);
                    }

                } break;
            case 0:// Печать в GUI ListBox
                {
                    for(int i=0;i<i1;i+=8) {
                        
                        if(i1-i>8) {
                        pointer_to_dialog->buf_Str.Format(_T("%.2X%.2X%.2X%.2X_%.2X%.2X%.2X%.2X"), 
                            pkt_data[0+i],pkt_data[1+i],pkt_data[2+i],pkt_data[3+i],
                            pkt_data[4+i],pkt_data[5+i],pkt_data[6+i],pkt_data[7+i]);
                        toOtherThreadList_withTimeout(pointer_to_dialog->my_list.GetSafeHwnd(),pointer_to_dialog->buf_Str);
                        }
                        else
                        {
                            ;
                        pointer_to_dialog->buf_Str.Format(_T("%.2X%.2X%.2X%.2X_%.2X%.2X"), 
                            pkt_data[0+i],pkt_data[1+i],pkt_data[2+i],pkt_data[3+i],
                            pkt_data[4+i],pkt_data[5+i]);
                        toOtherThreadList_withTimeout(pointer_to_dialog->my_list.GetSafeHwnd(),pointer_to_dialog->buf_Str);
                        }
                    }
                } break;
        } 
        printf("\n");
        }
    ;}
Re[3]: Winpcap в приложении
От: Pzz Россия https://github.com/alexpevzner
Дата: 18.03.19 10:22
Оценка: 2 (1)
Здравствуйте, milkpot, Вы писали:

M>Передача пакетов останавливается. Количество полученных пакетов каждый раз разное. Передача останавливается на уровне 2800-3400 пакетов.

M>Если ОС только запущена( не из спящего режима), то удается получить 4300-4500 пакетов.
M>Максимальное количество пакетов, которые надо получить — 4800 шт.

Выглядит так, будто пакеты теряются не при передаче, а при приеме.

Советую вынести прием пакетов в отдельную нить, и задрать этой нити приоритет до небес. Иначе всякая постоянная активность в венде, типа отрисовки экрана и работы с диском, постоянно будет прерывать ваш приниматель пакетов на очень ощутимое время (достаточное для переполнения буферов и потери пакетов).

Pzz>>Но вообще, этот ваш дизайн не полетит. Во-первых, чтобы получить скорость, сравнимую со скоростью ethernet'а, надо слать большие пакеты, а не маленькие. Во-вторых, нужен какой-то flow control. В третьих, должна быть защита от потери пакетов. А потеря пакетов может происходить даже, если все остальное сделано хорошо (правда, в нормальных условиях их должно тетяться совсем немного).


M>Можно вкратце рассказать о flow control и защите от потери пакетов.


В сеть нельзя просто лить с произвольной скоростью и надеяться, что все дойдет. Сеть может быть занята, пакеты могут теряться. Даже в локальной сети из одного сегмента это постоянно наблюдается, а если пакету предстоит по пути пройти несколько сетей, связанных роутерами, проблема становится еще более заметной.

Поэтому любые "настоящие" протоколы передачи данных предусматривают какие-то меры, чтобы обнаруживать переполнение сети, и снижать скорость, а так же обнаруживать потери данных и перепосылать недошедшее с первого раза.

Pzz>>А зачем работать на уровне голого Ethernet'а? Я понимаю, что TCP не во всякое устройство запишнешь, но UDP сделать совсем несложно, и сразу появляется возможность работать на уровне простых советских сокетов, а не через winpcap, к которому надо еще и драйвер ставить.

M>Логика устройства реализована в ПЛИС. Не могу сказать насколько трудоемко реализовать UDP.

Голый UDP реализовать не сложно, он всего лишь добавляет еще два незамысловатых заголовка, но по-хорошему, надо бы еще реализовать ARP и DHCP. Боюсь, это ваша ПЛИСка не потянет.

Я бы несколько усложнил логику ПЛИС. Пусть она научится принимать пакеты, содержащие команду "пошли мне данные от N до M". Тогда логику flow control'а и перепосылки потерянных данных можно реализовать на ПК.

И еще раз повторюсь, если работать маленькими пакетами, не получится приблизиться к скорости ethernet'а.
Re[3]: Winpcap в приложении
От: Pzz Россия https://github.com/alexpevzner
Дата: 18.03.19 10:26
Оценка:
Здравствуйте, milkpot, Вы писали:

M>Логика устройства реализована в ПЛИС. Не могу сказать насколько трудоемко реализовать UDP.


Еще вопрос. А откуда эта ПЛИСка знает, по какому адресу посылать пакеты?
Re[4]: Winpcap в приложении
От: milkpot Россия  
Дата: 18.03.19 13:28
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Здравствуйте, milkpot, Вы писали:


M>>Логика устройства реализована в ПЛИС. Не могу сказать насколько трудоемко реализовать UDP.


Pzz>Еще вопрос. А откуда эта ПЛИСка знает, по какому адресу посылать пакеты?


ПЛИС посылает широковещательные пакеты. Адрес источник Src зашит(задан аппаратно). Dst — все FF.
Получается, что посылается пачка из 4800 широковещательных пакетов.
Re[5]: Winpcap в приложении
От: Pzz Россия https://github.com/alexpevzner
Дата: 18.03.19 13:33
Оценка: 1 (1)
Здравствуйте, milkpot, Вы писали:

M>ПЛИС посылает широковещательные пакеты. Адрес источник Src зашит(задан аппаратно). Dst — все FF.

M>Получается, что посылается пачка из 4800 широковещательных пакетов.

Это паршиво. Потому что если в сети есть хоть одно 10-мегабитное устройство, подключенное прямо или через свитч, бродкасты будут передаваться на 10 мегабитах.
Re: Winpcap в приложении
От: m2l  
Дата: 18.03.19 16:20
Оценка: 2 (1)
Здравствуйте, milkpot, Вы писали:

M>Приложение использует Winpcap интерфейс.

M>Полностью принять все пакеты не получается. Изображение принимается не полностью.
M>Передача пакетов останавливается по какой-то причине.
Я в целом солидарен, с ответами выше, о криворукости автора железки за которую его надо этой железкой бить по голове.
Но учитывая некоторую безвыходность с твоей стороны — попробуй накостылить расширенные настройки сетевого адаптера.
В идеале было бы вообще попробовать нормальную сетевую типа intel X540/X710.
Если возможности нет, иди в панель управления > сетевые подключения > твой сетевой адаптер > Свойства > Настроить > Дополнительно.
И выставляй настройки:
Flow Control — Disable : отключаешь контроль скорости потока со стороны адаптера
Interrupt Moderation — Enable/Disable — поэкспериментируй с разным значением
IPv4 Checksum Offload — Disable — может карта путает твои пакета с IPv4 (если данные идут в RAW поверх L2)
Receive Buffers — наверное самое для тебя важно, ставь значение больше раз в десять-сто-тысячу, смотри поменяется ли что-то.
Speed & Duplex — убери Auto Negative и поставь скорость на которой работает железка
TCP Checksum Offload — Disable
UDP Checksum Offload — Disable
WOL & Shutdown Link Speed — Not Speed Down
Energy Efficient Ethernet — Dsable
Green Ethernet — Disable
Receive Side Scaling(RSS) — Попробуй с разными вариантами
После выставления настроек хотя бы раз перезагрузи комп.

Плюс посмотри настройки электропитания — и выстави в максимальную производительность, если это не так.
Плюс удали из системы все антивирусы/межсетевые экраны (не отключить, а удалить). Тот же касперский в силу эпичной криворукости авторов безбожно режет даже корректный, но не стандартный трафик. Причем хитрыми паттернами — когда например первые 4 пакета потока не проходят.

Можно ещё попробовать перетащить всё в Linux — попробовать записать данные tcpdump-ом и проверить — может там все будет норм. Плюс возможностей тонко рулить сетевыми настройками сильно больше.

M>На данный момент устройство посылает в ПК пакеты на скорости в 64 раза медленнее скорости Gigabit Ethernet.

Важней не скорость а равномерный межкадровый интервал. А в идеале — нормальные сетевой стэк.

M>Задача максимум стоит: посылать пакеты на скорости Gigabit Ethernet.

Боюсь с твоими исходными данными это почти не реально. Сам libpcap способе вытягивать гигабит почти полностью, но в силу того как сделана железка я сомневаюсь в результате.
Re[2]: Winpcap в приложении
От: milkpot Россия  
Дата: 19.03.19 09:29
Оценка:
Здравствуйте, m2l, Вы писали:

m2l>Здравствуйте, milkpot, Вы писали:


M>>Приложение использует Winpcap интерфейс.

M>>Полностью принять все пакеты не получается. Изображение принимается не полностью.
M>>Передача пакетов останавливается по какой-то причине.
m2l>Я в целом солидарен, с ответами выше, о криворукости автора железки за которую его надо этой железкой бить по голове.
m2l>Но учитывая некоторую безвыходность с твоей стороны — попробуй накостылить расширенные настройки сетевого адаптера.
m2l>В идеале было бы вообще попробовать нормальную сетевую типа intel X540/X710.
m2l>Если возможности нет, иди в панель управления > сетевые подключения > твой сетевой адаптер > Свойства > Настроить > Дополнительно.
m2l>И выставляй настройки:
m2l> Flow Control — Disable : отключаешь контроль скорости потока со стороны адаптера
m2l> Interrupt Moderation — Enable/Disable — поэкспериментируй с разным значением
m2l> IPv4 Checksum Offload — Disable — может карта путает твои пакета с IPv4 (если данные идут в RAW поверх L2)
m2l> Receive Buffers — наверное самое для тебя важно, ставь значение больше раз в десять-сто-тысячу, смотри поменяется ли что-то.
m2l> Speed & Duplex — убери Auto Negative и поставь скорость на которой работает железка
m2l> TCP Checksum Offload — Disable
m2l> UDP Checksum Offload — Disable
m2l> WOL & Shutdown Link Speed — Not Speed Down
m2l> Energy Efficient Ethernet — Dsable
m2l> Green Ethernet — Disable
m2l> Receive Side Scaling(RSS) — Попробуй с разными вариантами
m2l>После выставления настроек хотя бы раз перезагрузи комп.

m2l>Плюс посмотри настройки электропитания — и выстави в максимальную производительность, если это не так.

m2l>Плюс удали из системы все антивирусы/межсетевые экраны (не отключить, а удалить). Тот же касперский в силу эпичной криворукости авторов безбожно режет даже корректный, но не стандартный трафик. Причем хитрыми паттернами — когда например первые 4 пакета потока не проходят.

m2l>Можно ещё попробовать перетащить всё в Linux — попробовать записать данные tcpdump-ом и проверить — может там все будет норм. Плюс возможностей тонко рулить сетевыми настройками сильно больше.


M>>На данный момент устройство посылает в ПК пакеты на скорости в 64 раза медленнее скорости Gigabit Ethernet.

m2l>Важней не скорость а равномерный межкадровый интервал. А в идеале — нормальные сетевой стэк.

M>>Задача максимум стоит: посылать пакеты на скорости Gigabit Ethernet.

m2l>Боюсь с твоими исходными данными это почти не реально. Сам libpcap способе вытягивать гигабит почти полностью, но в силу того как сделана железка я сомневаюсь в результате.
Спасибо за ответ.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.