Bad file descriptor mit boost Threads und Sockets
-
Hallo,
ich wollte, um Boost Threads und Sockets besser zu verstehen, einen kleinen Server schreiben, der für jeden Client einen neuen Thread erzeugt und in diesem fortwähren einen Nachricht überträgt.
Leider führt das nur zu einem Bad file descriptor, wenn ich in dem Thread auf den Socket zugreifen möchte.#include <iostream> #include <string> #include <boost/thread.hpp> #include <boost/asio.hpp> using boost::asio::ip::tcp; using namespace std; void handleClient(tcp::socket* socket, string* message) { if(!socket || !message) return; while (1) { try { boost::asio::write(*socket, boost::asio::buffer(*message)); } catch (std::exception& e) { cerr << e.what() << std::endl; break; } sleep(1); } return; } int main(int argc, char* argv[]) { int port = 2323; if (argc > 1) port = atoi(argv[1]); boost::asio::io_service io_service; tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), port)); cout << "Starting on " << port << endl; string message = "Hello World!\n"; for (;;) { tcp::socket socket(io_service); acceptor.accept(socket); // handleClient(&socket, &message); boost::thread t(handleClient, &socket, &message); } return 0; }
-
Das Socket wird wohl zerstört, bevor der Thread überhaupt zu laufen beginnt.
-
for (;;) { tcp::socket socket(io_service); // socket wird erstellt acceptor.accept(socket); boost::thread t(handleClient, &socket, &message); // thread wird gestartet } // socket wird zerstört -> na viel Glück, wenn der Thread dann auf das Socket zugreift
Grüssli
-
Ah, danke, nun funktioniert's
#include <iostream> #include <string> #include <boost/thread.hpp> #include <boost/asio.hpp> using boost::asio::ip::tcp; using namespace std; void handleClient(tcp::socket* socket, string* message) { if(!socket || !message) return; while (1) { try { boost::asio::write(*socket, boost::asio::buffer(*message)); } catch (std::exception& e) { cerr << e.what() << std::endl; break; } sleep(1); } delete socket; return; } int main(int argc, char* argv[]) { int port = 2323; if (argc > 1) port = atoi(argv[1]); boost::asio::io_service io_service; tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), port)); cout << "Starting on " << port << endl; string message = "Hello World!\n"; for (;;) { tcp::socket* socket = new tcp::socket(io_service); acceptor.accept(*socket); boost::thread t(handleClient, socket, &message); } return 0; }
-
tonsiraff schrieb:
Ah, danke, nun funktioniert's
Nur wenn du Glück hast. Du spielst wohl gerne Russisch Roulette. Theoretisch könnten Threads weiterlaufen und der Hauptthread die
main
Funktion verlassen.message
würde ungültig werden und du greifst noch darauf zu. Wieso übergibst dumessage
überhaupt als Zeiger? Wieso nicht gleich als Kopie?
Auch die Übergabe vonsocket
als Zeiger halte ich nicht für so prickelnd.boost::asio
bietet eigentlich bereits die Möglichkeit, das ganze über Threads laufen zu lassen, also mehrere Threads für mehrere Clients zu verwenden, ohne dass du solche Verrenkungen machen musst.Grüssli
-
...