Zum Inhalt springen

boost asio: Problem mit Servererstellung in einer Klasse


Empfohlene Beiträge

Geschrieben

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

Geschrieben
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.

Geschrieben (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 :rolleyes:

Gruß

Happyman0815

Bearbeitet von Happyman0815
Geschrieben

	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.

Geschrieben

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

Geschrieben

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.

Geschrieben

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.

Geschrieben

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.

Geschrieben

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

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...