Using QThread , Signal() , Slot() So GUI won't freeze
-
@__d4ve__ said in Using QThread , Signal() , Slot() So GUI won't freeze:
pcap_loop(handle ,NUM_PACKETS_TO_CAPTURE ,packet_handler , nullptr);
pass this, instead of nullptr.
@mpergand said in Using QThread , Signal() , Slot() So GUI won't freeze:
pcap_loop(handle ,NUM_PACKETS_TO_CAPTURE ,packet_handler , this);and in the callback:
void workerobject::packet_handler(u_char* user_data, const struct pcap_pkthdr* packet_header, const u_char* packet_data) { ... WorkerObject* wo=qobject_cast<WorkerObject*>(user_data); assert(wo); wo->update_gui(...); -
@mpergand said in Using QThread , Signal() , Slot() So GUI won't freeze:
pcap_loop(handle ,NUM_PACKETS_TO_CAPTURE ,packet_handler , this);and in the callback:
void workerobject::packet_handler(u_char* user_data, const struct pcap_pkthdr* packet_header, const u_char* packet_data) { ... WorkerObject* wo=qobject_cast<WorkerObject*>(user_data); assert(wo); wo->update_gui(...);@mpergand Your solution doesn't work / not understandable
packet_handler function just process the data and I use emit to pass the processed data to function which will update the GUI the main issue i encounter here is with static / not static functions errors i mentioned above , any way thank you for trying
-
I have error with :
pcap_loop(handle, NUM_PACKETS_TO_CAPTURE, packet_handler, nullptr);the error : C:\Users\Dave\Desktop\C++ Exercises\Qt Creator Projects\Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:88: error: Reference to non-static member function must be calledfull code here : Qt Packet Viewer Code
-
I have error with :
pcap_loop(handle, NUM_PACKETS_TO_CAPTURE, packet_handler, nullptr);the error : C:\Users\Dave\Desktop\C++ Exercises\Qt Creator Projects\Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:88: error: Reference to non-static member function must be calledfull code here : Qt Packet Viewer Code
Sum up of all the errors :
\Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:55: error: C3861: 'update_gui': identifier not found \Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:88: error: C3867: 'workerobject::packet_handler': non-standard syntax; use '&' to create a pointer to member \Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:55: error: Use of undeclared identifier 'update_gui' \Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:88: error: Reference to non-static member function must be called -
Sum up of all the errors :
\Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:55: error: C3861: 'update_gui': identifier not found \Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:88: error: C3867: 'workerobject::packet_handler': non-standard syntax; use '&' to create a pointer to member \Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:55: error: Use of undeclared identifier 'update_gui' \Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:88: error: Reference to non-static member function must be called@__d4ve__ said in Using QThread , Signal() , Slot() So GUI won't freeze:
\Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:55: error: C3861: 'update_gui': identifier not found
Please show the code which causes this error...
-
@__d4ve__ said in Using QThread , Signal() , Slot() So GUI won't freeze:
\Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:55: error: C3861: 'update_gui': identifier not found
Please show the code which causes this error...
-
@jsulm
full code here : Qt Packet Viewer Codeseems that workerobject.cpp does the error
-
@__d4ve__ Sorry, but I'm not going to search in that link for relevant parts. You can simply post the code (and only that code) which causes this errors...
@jsulm
The error occurs with packet_handler & pcap_loop(handle, NUM_PACKETS_TO_CAPTURE, packet_handler, nullptr);
which is calling itvoid packet_handler(u_char* user_data, const struct pcap_pkthdr* packet_header, const u_char* packet_data) { std::stringstream packetInfo; // Add packet information to the stringstream packetInfo << std::endl; packetInfo << "Packet Information:" << std::endl; packetInfo << "Capture Length: " << std::setw(5) << packet_header->caplen << std::endl; packetInfo << "Packet Length: " << std::setw(5) << packet_header->len << std::endl; packetInfo << "Packet Data:" << std::endl; // Print packet data as hexadecimal and ASCII int byte_count = 0; for (unsigned int i = 0; i < packet_header->caplen; i++) { packetInfo << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(packet_data[i]) << " "; byte_count++; // Add extra space after every 8 bytes for better readability if (byte_count % 8 == 0) packetInfo << " "; // Add newline after every 16 bytes and print ASCII representation if (byte_count % 16 == 0) { packetInfo << "| "; for (unsigned int j = i - 15; j <= i; j++) { if (packet_data[j] >= 32 && packet_data[j] <= 126) packetInfo << static_cast<char>(packet_data[j]); else packetInfo << "."; } packetInfo << std::endl; } } std::string packetInfoString = packetInfo.str(); QString packetInfoQString = QString::fromStdString(packetInfoString); QMutexLocker locker(&Mutex); std::cout << packetInfoString << std::endl; // emit packetCaptured(packetInfoQString); emit update_gui(packetInfoQString); } // loop through packets with choosen device ---- should add variable device // The pcap_loop starter // in current stat device name need to be inputed void workerobject::packet_looper() { //QString selectedDev_qt; // Initialize it with the selected device name char errbuf[PCAP_ERRBUF_SIZE]; pcap_if_t* alldevs = nullptr; pcap_if_t* selectedDev = nullptr; // Iterate over the list of interfaces and find the selected adapter for (pcap_if_t* dev = alldevs; dev != nullptr; dev = dev->next) { if (selectedDev_qt == dev->description) { selectedDev = dev; break; } } pcap_t* handle = pcap_open_live(selectedDev->name, BUFSIZ, 1, 1000, errbuf); if (handle == nullptr) { std::cerr << "Error opening interface for packet capture: " << errbuf << std::endl; pcap_freealldevs(alldevs); return; // Stop further execution if opening handle fails } QMutexLocker unlock(&Mutex); pcap_loop(handle, NUM_PACKETS_TO_CAPTURE, packet_handler, nullptr); // Close the packet capture handle pcap_close(handle); // Free the allocated memory for the interface list pcap_freealldevs(alldevs); } -
@jsulm
The error occurs with packet_handler & pcap_loop(handle, NUM_PACKETS_TO_CAPTURE, packet_handler, nullptr);
which is calling itvoid packet_handler(u_char* user_data, const struct pcap_pkthdr* packet_header, const u_char* packet_data) { std::stringstream packetInfo; // Add packet information to the stringstream packetInfo << std::endl; packetInfo << "Packet Information:" << std::endl; packetInfo << "Capture Length: " << std::setw(5) << packet_header->caplen << std::endl; packetInfo << "Packet Length: " << std::setw(5) << packet_header->len << std::endl; packetInfo << "Packet Data:" << std::endl; // Print packet data as hexadecimal and ASCII int byte_count = 0; for (unsigned int i = 0; i < packet_header->caplen; i++) { packetInfo << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(packet_data[i]) << " "; byte_count++; // Add extra space after every 8 bytes for better readability if (byte_count % 8 == 0) packetInfo << " "; // Add newline after every 16 bytes and print ASCII representation if (byte_count % 16 == 0) { packetInfo << "| "; for (unsigned int j = i - 15; j <= i; j++) { if (packet_data[j] >= 32 && packet_data[j] <= 126) packetInfo << static_cast<char>(packet_data[j]); else packetInfo << "."; } packetInfo << std::endl; } } std::string packetInfoString = packetInfo.str(); QString packetInfoQString = QString::fromStdString(packetInfoString); QMutexLocker locker(&Mutex); std::cout << packetInfoString << std::endl; // emit packetCaptured(packetInfoQString); emit update_gui(packetInfoQString); } // loop through packets with choosen device ---- should add variable device // The pcap_loop starter // in current stat device name need to be inputed void workerobject::packet_looper() { //QString selectedDev_qt; // Initialize it with the selected device name char errbuf[PCAP_ERRBUF_SIZE]; pcap_if_t* alldevs = nullptr; pcap_if_t* selectedDev = nullptr; // Iterate over the list of interfaces and find the selected adapter for (pcap_if_t* dev = alldevs; dev != nullptr; dev = dev->next) { if (selectedDev_qt == dev->description) { selectedDev = dev; break; } } pcap_t* handle = pcap_open_live(selectedDev->name, BUFSIZ, 1, 1000, errbuf); if (handle == nullptr) { std::cerr << "Error opening interface for packet capture: " << errbuf << std::endl; pcap_freealldevs(alldevs); return; // Stop further execution if opening handle fails } QMutexLocker unlock(&Mutex); pcap_loop(handle, NUM_PACKETS_TO_CAPTURE, packet_handler, nullptr); // Close the packet capture handle pcap_close(handle); // Free the allocated memory for the interface list pcap_freealldevs(alldevs); }@__d4ve__
Sorry, what does "which is calling it" have anything to do with error? It is a compiler error for an undefined identifier.What are lines #55 and #88 in
workerobject.cpp? That is what we need to know!If it errors on the line
emit update_gui(packetInfoQString);you show above (but I only see one occurrence, how can that be both lines?) then
update_gui()is not declared to the compiler at that point. -
@__d4ve__
Sorry, what does "which is calling it" have anything to do with error? It is a compiler error for an undefined identifier.What are lines #55 and #88 in
workerobject.cpp? That is what we need to know!If it errors on the line
emit update_gui(packetInfoQString);you show above (but I only see one occurrence, how can that be both lines?) then
update_gui()is not declared to the compiler at that point. -
@__d4ve__
Sorry, what does "which is calling it" have anything to do with error? It is a compiler error for an undefined identifier.What are lines #55 and #88 in
workerobject.cpp? That is what we need to know!If it errors on the line
emit update_gui(packetInfoQString);you show above (but I only see one occurrence, how can that be both lines?) then
update_gui()is not declared to the compiler at that point. -
I'm wondering if there is a better way to accomplish this task maybe using Tins .. but that's and issue by itself
@__d4ve__ said in Using QThread , Signal() , Slot() So GUI won't freeze:
I'm wondering if there is a better way to accomplish this task maybe using Tins
How should this change something? It doesn't matter what lib you use, whether it's pcap, tins or packet sniffer 9000. If you want to keep your GUI responsive while using a synchronous library or function, you have to move it to a different thread.
Threading in general is a "not-so-easy" task, esp. with limited programming knowledge, but IMO a Worker-Thread is one of the easier approaches and it matches your requirements as well.
Read about how it works (in this topic are already plently of links) and be aware of what you really want to do (what function you want to run? what data should be send from where to where?... etc.)
-
@__d4ve__ said in Using QThread , Signal() , Slot() So GUI won't freeze:
I'm wondering if there is a better way to accomplish this task maybe using Tins
How should this change something? It doesn't matter what lib you use, whether it's pcap, tins or packet sniffer 9000. If you want to keep your GUI responsive while using a synchronous library or function, you have to move it to a different thread.
Threading in general is a "not-so-easy" task, esp. with limited programming knowledge, but IMO a Worker-Thread is one of the easier approaches and it matches your requirements as well.
Read about how it works (in this topic are already plently of links) and be aware of what you really want to do (what function you want to run? what data should be send from where to where?... etc.)
-
The task is keep GUI responsive , and yes you are right we achieved at this point the threading stuff the issue now have changed into running pcap_loop() which isn't working because it requires static function and I use non-static function
@__d4ve__ said in Using QThread , Signal() , Slot() So GUI won't freeze:
which isn't working because it requires static function and I use non-static function
This is probably not the reason behind this issue...
I can only repeat what @JonB and others have said...
Look at the lines 55 and 88 and check what's written there or post it here. Because it's a pain to check your linked archieve when you have the code right in front of you. So probably nobody will dig through your whole project to find these two or more lines which will produce your current error. -
@__d4ve__ said in Using QThread , Signal() , Slot() So GUI won't freeze:
which isn't working because it requires static function and I use non-static function
This is probably not the reason behind this issue...
I can only repeat what @JonB and others have said...
Look at the lines 55 and 88 and check what's written there or post it here. Because it's a pain to check your linked archieve when you have the code right in front of you. So probably nobody will dig through your whole project to find these two or more lines which will produce your current error. -
line 55 :
emit update_gui(packetInfoQString);line 88 :
pcap_loop(handle ,NUM_PACKETS_TO_CAPTURE ,packet_handler , nullptr);@__d4ve__ said in Using QThread , Signal() , Slot() So GUI won't freeze:
emit update_gui(packetInfoQString);
Now, look at the first error message:
"\Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:55: error: C3861: 'update_gui': identifier not found"It tells you that update_gui is not known. Did you declare update_gui as signal in that class?
-
@__d4ve__ said in Using QThread , Signal() , Slot() So GUI won't freeze:
emit update_gui(packetInfoQString);
Now, look at the first error message:
"\Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:55: error: C3861: 'update_gui': identifier not found"It tells you that update_gui is not known. Did you declare update_gui as signal in that class?
Yes,
signals: void update_gui(QString packetInfoQString); };The issue is here : pcap_loop got call back function named packet_handle - this function emit update_gui
but the problem here that pcap_loop requires static function , while packet_handle can't be static function
try to run the project that's very short code
-
Yes,
signals: void update_gui(QString packetInfoQString); };The issue is here : pcap_loop got call back function named packet_handle - this function emit update_gui
but the problem here that pcap_loop requires static function , while packet_handle can't be static function
try to run the project that's very short code
@__d4ve__
If you mean that signalupdate_gui()is a member ofMainWindowthen you won't be able to call it viaWorkerObject* wo=qobject_cast<WorkerObject*>(user_data); assert(wo); wo->update_gui(...);You presumably need the signal defined somewhere accessible from
WorkerObjectand then a slot inMainWindowto receive the signal from the worker object.Get the principle suggested by @mpergand working.