Как создать новый stream для совместимости pcap_loop () и gtk_main ()?

Эти две функции представляют собой бесконечные петли,

и программа зависает, однажды вызывается в том же streamе.

gtk_main(); ... pcap_loop(adhandle, 0, packet_handler, NULL); 

Когда я нажимаю кнопку «Пуск», я хочу, чтобы pcap начал работать, и если я нажму кнопку «Стоп», остановитесь на pcap .

Как создать дочерний stream и запустить pcap_loop(adhandle, 0, packet_handler, NULL); вместо?

Если я что-то не хватает, ваша проблема заключается в том, что и GTK +, и libpcap организованы вокруг событий, запущенных из основного цикла. Не просматривая документацию, я не знаю о GTK +, но есть еще один режим работы для libpcap: вы можете использовать pcap_next() или pcap_next_ex() не отказываясь от контроля над streamом вашей программы.

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

Взгляните на документацию для g_thread_create() . Также прочитайте этот учебник и это сообщение в блоге для получения дополнительной информации о многопоточных программах GTK.

В основном вы хотите вызвать gtk_main() когда вы создали свой пользовательский интерфейс и начали свою программу. Затем в pcap_loop() вызове для кнопки «начать» создайте новый stream с g_thread_create() в котором вы вызываете pcap_loop() .

Кнопка «Стоп» немного сложнее, так как GLib не позволяет прерывать stream из другого streamа. Вам нужно будет создать какой-то механизм сигнализации; например, флаг логического прерывания, защищенный GMutex . В g_mutex_lock() кнопки остановки заблокируйте флаг с помощью g_mutex_lock() , установите его и разблокируйте с помощью g_mutex_unlock() . В вашем packet_handler также заблокируйте флаг, прочитайте его и откройте. Если флаг установлен, тогда вызовите все, что вы вызываете, чтобы pcap вырвался из цикла.