Здравствуйте!Пишу приложение с использованием Qt. Имеется поток назначение которого, - захват данных, приходящих на сетевой интерфейс компьютера. Для захвата используется библиотека Libpcap. В потоке вызывается блокирующая функция захвата пакетов, например, pcap_loop. Необходимо обеспечить возможность выхода из данной функции, не дожидаясь события захвата пакета. Например, поток висит в функции и в это время пользователь решает изменить выражение фильтра. Чтобы заново скомпилировать выражение фильтра, необходимо, чтобы блокирующая функция вернула управление потоку. Каким образом можно решить данную задачу?
Спасибо!
> Здравствуйте!
> Пишу приложение с использованием Qt. Имеется поток назначение которого, - захват данных,
> приходящих на сетевой интерфейс компьютера. Для захвата используется библиотека Libpcap.
> В потоке вызывается блокирующая функция захвата пакетов, например, pcap_loop. Необходимо
> обеспечить возможность выхода из данной функции, не дожидаясь события захвата пакета.
> Например, поток висит в функции и в это время пользователь решает
> изменить выражение фильтра. Чтобы заново скомпилировать выражение фильтра, необходимо,
> чтобы блокирующая функция вернула управление потоку. Каким образом можно решить данную
> задачу?
> Спасибо!давно уже есть Ethereal
>[оверквотинг удален]
>> Пишу приложение с использованием Qt. Имеется поток назначение которого, - захват данных,
>> приходящих на сетевой интерфейс компьютера. Для захвата используется библиотека Libpcap.
>> В потоке вызывается блокирующая функция захвата пакетов, например, pcap_loop. Необходимо
>> обеспечить возможность выхода из данной функции, не дожидаясь события захвата пакета.
>> Например, поток висит в функции и в это время пользователь решает
>> изменить выражение фильтра. Чтобы заново скомпилировать выражение фильтра, необходимо,
>> чтобы блокирующая функция вернула управление потоку. Каким образом можно решить данную
>> задачу?
>> Спасибо!
> давно уже есть EtherealА подробнее можно?
Предлагается использовать Etheral вместо Libpcap, насколько я понял. Не знаком ни с Libpcap ни с Etheral, но думаю можно добавить таймаут в ту блокирующую функцию, чтобы периодически её запускать во время работы, но и обрабатывать различные ситуации вроде той, когда пользователь решит изменить выражение фильтра. Либо добавить(использовать) управление заданием той самой функции из другого потока.
> Предлагается использовать Etheral вместо Libpcap, насколько я понял. Не знаком ни
> с Libpcap ни с Etheral, но думаю можно добавить таймаут
> в ту блокирующую функцию, чтобы периодически её запускать во время работы,
> но и обрабатывать различные ситуации вроде той, когда пользователь решит изменить
> выражение фильтра. Либо добавить(использовать) управление заданием той самой функции
> из другого потока."Предлагается использовать Etheral". Это не решение проблемы, а попытка от нее уйти. Менять что-то в кишках блокирующей функции я не могу, поскольку она библиотечная. По-видимому, придется принудительно завершать поток, в котором вызвана функция и перезапускать его
> принудительно завершать поток, в котором вызвана функция и перезапускать егоЭто не решение, а костыль, и очень опасный. Возможно вам стоит получше изучить документацию, то, что я вам предложил в библиотеке скорее всего реализовано.
>принудительно завершать поток, в котором вызвана функция и перезапускать егоВы знаете на каком месте поток остановится и какие ресурсы он может занять, но не успеть освободить и кроме того вы готовы постоянно плодить новые потоки? Почитайте документацию, например эту http://www.tcpdump.org/pcap.html ,либо дождитесь завершения потока.
int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
Второй аргумент
Following that is an integer that tells pcap_loop() how many packets it should sniff for before returning (a negative value means it should sniff until an error occurs).Устанавливайте количество, переменную cnt, после чего запускайте обработчик ввода пользователя и снова pcap_loop. И никаких блокировок не будет
> int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
> Второй аргумент
> Following that is an integer that tells pcap_loop() how many packets it
> should sniff for before returning (a negative value means it should
> sniff until an error occurs).
> Устанавливайте количество, переменную cnt, после чего запускайте обработчик ввода пользователя
> и снова pcap_loop. И никаких блокировок не будетДаже если я вызову pcap_loop со значением cnt равным "1", поток будет висеть в этой функции до скончания века, если данный пакет не будет принят по каким-то причинам. Как Вы предлагаете в данном случае выйти из pcap_loop?
Теперь по поводу таймаута. Действительно, в библиотеке есть возможность задать таймаут. Но решение задачи выходом из блокирующей функции по таймауту не является оптимальным. Можно сделать, как Вы предложили: вываливаться из функции по таймауту, проверять управляющую информацию и возвращаться обратно. Такую же проверку нужно делать и в callback функции, чтобы иметь возможность выходить из функции в случае отсутствия возникновения таймаутов. При выходе из блокирующей функции программа становится нечувствительной к событиям приема пакетов. То есть мы начинаем терять пакеты. Такой подход заведомо снижает эффективность работы программы.
Да, я предполагал, что, возможно, это приведет к потере пакетов, скорость может быть огромная. Вы проверяли это? В любом случае в библиотеке должны быть механизмы, решающие эту проблему без потери пакетов, хотя, может быть, и на более мощном железе. Как бы логично, что опрос тех пакетов никак не может помешать проверить в этой же функции один единственный флаг о необходимости завершить этот опрос, в том же коллбэке больше операций выполняется.