[gelöst]C++ boost asio/Socket als variable übergeben: Keine Daten empfangen



  • Hallo Ihr lieben.
    Zuerst: Ich nutze noch Boost 1.35. da ich die neuste Boostlibrary nicht kompilieren kann (NTVDM CPU has encountered an illegal instruction).

    Doch nun zum Phänomen:

    Ich baue mit boost:asio eine Socketverbindung zu einer Software auf und sende darüber zwei Befehle, was auch incl. Empfang funktioniert.
    Also Befehl1: Senden-Empfangen, Befehl2: Senden-Empfangen.

    Den Zweiten Befehl sollte ich nun in einer extra Funktion senden/empfangen.
    Also übergebe ich den Socket als Zeiger und sende in der Funktion den 2. Befehl, was auch funktioniert.Allerdings kann ich dann nichts empfangen, bzw. der Empfangsbuffer ist leer, da kann ich machen was ich will.

    Dann habe ich ein wenig herumexperimentiert:

    Befehl1 in der extra Funktion empfangen-> funktioniert.

    Mit normalen Windows Sockets: Befehl1 Senden/empfangen, dann Befehl2 in der Funktion Senden/Empfangen-> Funktioniert!

    Es scheint also nicht am Prinzip oder an der Software zu liegen, sondern es muss irgendwie mit boost zusammenhängen.

    Hier der Teil-Quellcode:

    *string ip_client_str = ip_client;
    	string port_interface_str = str( boost::format("%1%") % CUservariable::PORT_INTERFACE_ORIG);
    
        tcp::resolver resolver(io_service);
        tcp::resolver::query query(ip_client_str,port_interface_str );
        tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
        tcp::resolver::iterator end;
    
    	tcp::socket socket(io_service);
        boost::system::error_code error = boost::asio::error::host_not_found;
        while (error && endpoint_iterator != end)
        {
          socket.close();
          socket.connect(*endpoint_iterator++, error);	  
        }
        if (error)
          throw boost::system::system_error(error);
    
        boost::asio::streambuf request;
        std::ostream request_stream(&request);
    	boost::asio::streambuf response;
    	std::istream response_stream(&response);
        std::string erg_socksize;
    
    	request_stream << "Befehl2";     
        boost::asio::write(socket, request);    
        boost::asio::read_until(socket, response, "\0");	
        // Check that response is OK.   
        response_stream >> erg_socksize;//OK
    
    CCheckLogin chklgn;
    	 chklgn.logintext = erg_socksize;
    	 bool isSockSize = chklgn.getLogin([b]&socket[/b]);
    

    Deklaration der Funktion:

    class CCheckLogin
    {
    ..
    
    public:
    
    	bool getLogin(boost::asio::ip::tcp::socket *);	
    
    ..
    
    ....
    

    Implementierung:

    ....
    bool CCheckLogin::getLogin_str(boost::asio::ip::tcp::socket * socket)
     {.......
    request_stream << stdPwdSend;
    iSend = boost::asio::write(*socket, request); 
    boost::asio::read_until(*socket, response, "\0"); [b]//STREAM IST LEER![/b]
    ....
    

    In der Software sehe ich, daß der Befehl ankommt und versendet wird, nur kann ich ihn nicht empfangen.
    Wie gesagt, mache ich das ohne "extra" Funktion hintereinander, funktioniert es bzw. ich empfange was.
    Kann es an der Referenz auf den Socket liegen? Aber dann könnte ja die Software nichts empfangen?

    Woran kann das liegen, daß ich beim empfangen in der Funktion nichts bekomme?



  • Was für ein Typ hat response und wie wird die Variable initialisiert?



  • Response ist ein streambuf, der innerhalb der Funktion angelegt wird:

    bool CCheckLogin::getLogin_str(boost::asio::ip::tcp::socket * socket)
    {.......
    boost::asio::streambuf response;
    std::istream response_stream(&response)
    ...
    request_stream << stdPwdSend;
    iSend = boost::asio::write(*socket, request);
    boost::asio::read_until(*socket, response, "\0"); //STREAM IST LEER!



  • Hat sich erledigt.
    Das Problem lag an read-until - diese Funktion liest bis ein bestimmtes Zeichen empfangen wurde, in meinem Fall '\0', der Buffer war dann aber noch nicht leer, sondern war noch aufgefüllt mit nullen.
    mir der Funktion read_some kann ich die Länge angeben, dann wird auch alles abgeholt und es kommen auch die gewünschten Ergebnisse.
    Danke für die Hilfe.



  • ⚠ Mit read_some(..) werden nicht zwingend soviele Daten gelesen wie dein Buffer gross ist, sondern etwas zwischen 0 und Buffer Grösse an Bytes! Du musst selbst prüfen ob das Ende deiner Nachricht schon angekommen ist, ansonsten weiterlesen und die Daten aufkumulieren - halt das Framing Protokoll umsetzten.



  • Ja, das mache ich so:
    Lesen, prüfen ob alles da ist, wenn nicht, den rest abholen, so lange bis alles da ist.



  • Wieso kannst du Boost nicht kompilieren unter Windows7 mit VS2010 und auch VS2012 kein Problem, per CMD und b2. Dauert halt etwas länger als z.B. wxWidgets.

    bootstrap.bat
    .\b2 toolset=msvc --build-type=complete --libdir=<boostdir>\lib\i386 install
    

    Mehr mache ich nicht außer beim 64Bit Build.



  • Wie gesagt, es kommt die Meldung, daß NTVDM CPU eine illegal instruction encountered hat 🙂 Auch direkt auf der Commandozeile geht es wegen diesem Problem nicht.


Anmelden zum Antworten