Happyman0815 Geschrieben 28. Mai 2009 Geschrieben 28. Mai 2009 Hallo Leute! Ich habe ein Problem bei der Erstellung einer Server Klasse. Also: Ich muss in meiner Klasse Objekte von anderen Klassen erstellen. Diesen Klassen muss ich eine in der Klasse erstellten Variable übergeben und genau das funktioniert nicht. Auszug aus dem Header: boost::asio::io_service io_service; tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 13)); tcp::socket socket(io_service); Die Variable io_service muss für die Socketerstellung den Klassen socket und acceptor übergeben werden. Genau das geht nicht. Weiß jemand einen ausweg? Gruß Happyman0815 Zitieren
Klotzkopp Geschrieben 28. Mai 2009 Geschrieben 28. Mai 2009 das funktioniert nicht und das geht nicht sind keine ausreichenden Fehlerbeschreibungen. Hast du irgendwo eine using-Direktive für den Namespace boost::asio? Dann sollte das io_service-Objekt vielleicht nicht gerade genauso heißen wie die Klasse. Das ist aber nur eine Vermutung. Für eine ordentliche Diagnose musst du eine ordentlich Fehlerbeschreibung abliefern. Zitieren
Happyman0815 Geschrieben 28. Mai 2009 Autor Geschrieben 28. Mai 2009 (bearbeitet) Da ich den Fehler nicht genau lokalisieren kann (es ist wohl ein verständnis Problem) poste ich einfach mal die gesamte Klasse: Class Header: #include <iostream> #include <string> #include <boost/asio.hpp> #include <boost/thread/thread.hpp> using boost::asio::ip::tcp; class create_serv_com : public tcp::acceptor { public: boost::array<char, 48259> buf_send; boost::array<char, 48259> buf_recv; boost::array<char, 48259> buf; boost::asio::io_service io_service; boost::system::error_code error; boost::system::error_code ignored_error; tcp::acceptor acceptor( io_service, tcp::endpoint(tcp::v4() , 13 )); tcp::socket socket(io_service); /*class Klasse { private: int& r; int const c; public: Klasse(int i) : r(i), c(i) { } };*/ void send(); void recv(); create_serv_com( boost::asio::io_service io_service_ );// : io_service(io_service_); ~create_serv_com(void); }; Class Quell: #include "StdAfx.h" #include "create_serv_com.h" #include <string> #include <iostream> #include <boost/asio.hpp> using boost::asio::ip::tcp; create_serv_com::create_serv_com(void) { buf_send = "Test!\n"; try { acceptor.accept(socket); } catch (std::exception& e) { std::cerr << e.what() << std::endl; } } create_serv_com::~create_serv_com(void) { } void create_serv_com::send() { try{ //Schreiben boost::asio::write(socket, boost::asio::buffer(buf_send), boost::asio::transfer_all(), ignored_error); //schreibt solange bis speicher voll (ca. 48259 Bytes) catch (std::exception& e) { std::cerr << e.what() << std::endl; } } void create_serv_com::recv() { try{ //Lesen size_t len = socket.read_some(boost::asio::buffer(buf_re), error); //Blockierende Funktion! if (error == boost::asio::error::eof) break; // Connection closed cleanly by peer. else if (error) throw boost::system::system_error(error); // Some other error. std::cout.write(buf_recv.data(), len); //Ausgabe des gelesenen } catch (std::exception& e) { std::cerr << e.what() << std::endl; } } Der Sinn ist es eine Klasse aufzubauen die einen Server darstellt, mit einem (bis jetzt) vorgegebenen Port. Nach Erstellung des Objektes (Server) kann man mit den Member Funktionen recv(..) und send(..) Daten verschicken bzw. empfangen. Nun hapert es aber an den Objekterstellung die für die Sockets notwendig sind: boost::asio::io_service io_service; tcp::acceptor acceptor( io_service, tcp::endpoint(tcp::v4() , 13 )); tcp::socket socket(io_service); Hier übergebe ich den Klassen socket und acceptor das Objekt io_service. Genau das funktioniert aber nicht! Ich muss irgendwie eine Lösung dafür finden. Die Objekte socket, acceptor und io_service sollte global in der Klasse erreichbar sein. Ehemals war das ein Tutoriell für einen Server der mit Boost Bibliotheken erstellt wird (wegen plattformunabhängigkeit). Da funktioniert der Code auch bestens (es wurde dort alles in die main geschrieben). Jetzt habe ich den Code in eine Klasse gepackt und ich bekomm nur noch Probleme Gruß Happyman0815 Bearbeitet 28. Mai 2009 von Happyman0815 Zitieren
Klotzkopp Geschrieben 28. Mai 2009 Geschrieben 28. Mai 2009 tcp::acceptor acceptor( io_service, tcp::endpoint(tcp::v4() , 13 )); tcp::socket socket(io_service); [/CODE]Ich weiß nicht, ob du dir dessen bewusst bist, aber das sind Methodendeklarationen, keine Objekte. Du kannst Member nicht innerhalb der Klassendefinition initialisieren, das geht nur im Konstruktor. Durch die Klammern werden das Methoden. Außerdem halte ich es für seltsam, dass create_serv_com sowohl einen tcp::acceptor-Member hat als auch von tcp::acceptor erbt. Zitieren
Happyman0815 Geschrieben 28. Mai 2009 Autor Geschrieben 28. Mai 2009 Wenn ich alles in eine Funktion packe, funktioniert es: using boost::asio::ip::tcp; void com_serv() { boost::asio::io_service io_service; boost::system::error_code error; boost::system::error_code ignored_error; try { tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 13)); tcp::socket socket(io_service); acceptor.accept(socket); while(true) { mutex.lock(); std::cout << "Hello World!" << std::endl; wait(1000); mutex.unlock(); //Schreiben boost::asio::write(socket, boost::asio::buffer(buf), boost::asio::transfer_all(), ignored_error); //schreibt solange bis speicher voll (ca. 48259 Bytes) //Lesen size_t len = socket.read_some(boost::asio::buffer(buf), error); //Blockierende Funktion! if (error == boost::asio::error::eof) break; // Connection closed cleanly by peer. else if (error) throw boost::system::system_error(error); // Some other error. std::cout.write(buf.data(), len); //Ausgabe des gelesenen } } catch (std::exception& e) { std::cerr << e.what() << std::endl; } } ich habe nicht ansatzweise eine Ahnung. Wenn socket und acceptor Methoden sind, warum werden Sie dann z.B. wie folgt verwendet: size_t len = socket.read_some(boost::asio::buffer(buf_re), error); Daran sitz ich schon seit 5 Stunden :bimei Zitieren
Klotzkopp Geschrieben 28. Mai 2009 Geschrieben 28. Mai 2009 Wenn socket und acceptor Methoden sind, warum werden Sie dann z.B. wie folgt verwendet:Sie sollen natürlich keine sein, aber wenn du den Code unverändert aus einer Funktion in eine Klassendefinition verschiebst, dann wird daraus eine Methode. Dieselbe Zeile Code tcp::socket socket(io_service); bewirkt innerhalb einer Funktion die Deklaration eines socket-Objekts, an dessen Konstruktor das io_service-Objekt übergeben wird. Wenn dieser Code aber in einer Klassendefinion steht, deklariert er eine Methode namens socket (!), die einen (namenlosen) io_service-Parameter hat und ein tcp::socket-Objekt zurückgibt. Erschwerend (bezüglich des Verständnisses) kommt hier hinzu, dass du konsequent die Objekte genauso genannt hast wie die Klassen. Wenn das ein Objekt sein soll, dann muss die Initialisierung aus der Klassendefinition raus und in die Initialisierungsliste des Konstruktors. class create_serv_com : public tcp::acceptor { public: //... tcp::acceptor acceptor; tcp::socket socket; //...[/code] [code]create_serv_com::create_serv_com() : acceptor( io_service, tcp::endpoint(tcp::v4() , 13 )), socket(io_service) { // ... Und wie bereits gesagt, entweder ein acceptor-Member oder eine Vererbung. Beides gleichzeitig ist mit hoher Wahrscheinlichkeit Blödsinn. Außerdem rate ich dir dringend, die Variablen anders zu benennen. Die Fehlersuche wird nur unnötig schwerer, wenn ein Bezeichner sowohl ein Objekt als auch ein Typ sein kann. Zitieren
Happyman0815 Geschrieben 29. Mai 2009 Autor Geschrieben 29. Mai 2009 hmmm... bei deiner Variante meckert er jetzt. boost::asio::io_service io_service; tcp::acceptor acceptor2; tcp::socket socket2; create_serv_com( ) : acceptor2( io_service, tcp::endpoint(tcp::v4() , 13 )), socket2(io_service){} Fehler: Error 1 error C2512: 'boost::asio::basic_socket_acceptor<Protocol>' : no appropriate default constructor available 47 TCP Server Aber irgendwie so in der Richtung müsste es wohl funktionieren. Zitieren
Klotzkopp Geschrieben 29. Mai 2009 Geschrieben 29. Mai 2009 Error 1 error C2512: 'boost::asio::basic_socket_acceptor<Protocol>' : no appropriate default constructor available Erbt deine Klasse immer noch von acceptor? Falls das wirklich gewollt ist (was ich immer noch stark bezweifle), musst du in der Initialisierungsliste auch die Basisklasse initialisieren, denn die hat offensichtlich keinen Defaultkonstruktor. Zitieren
Happyman0815 Geschrieben 29. Mai 2009 Autor Geschrieben 29. Mai 2009 JA das wars! Das hatte ich noch stehen. THX!! THX!! THX!! THX!! THX!! THX!! THX!! THX!! THX!! THX!! THX!! THX!! THX!! Man da hab ich doch tatsächlich jetzt gut 9 Stunden mit verbracht -.- Endlich funktionierts :beagolisc THX! Gruß HAppyman0815 Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.