2017-08-16 17 views
0

Überprüfen Sie diese beiden einfachen Server-Client-Programm. Wie in Bedingung eins. Client überträgt Daten an Server und Vies Versa ist möglich. aber wenn ich versuche, gleichzeitig oder nacheinander zu machen. Sie sind im Race-Zustand festgefahren.Einfache Datenübertragung in Boost :: asio?

Client-Programm:

#include <boost/asio.hpp> 

void read(boost::asio::ip::tcp::socket& socket1, boost::system::error_code error_code) 
{ 
    boost::asio::streambuf streambuf; 
    boost::asio::read(socket1, streambuf, error_code); 

    std::istream streambuf1(&streambuf); 
    std::string string; 
    streambuf1 >> string; 
    std::cout << string << std::endl; 
} 

void write(boost::asio::ip::tcp::socket& socket1, boost::system::error_code error_code) 
{ 
    std::string string("hello"); 
    boost::asio::write(socket1, boost::asio::buffer(string), error_code); 
} 

int main(int argc, char *argv[]) 
{ 
    boost::asio::io_service io_service; 
    boost::asio::ip::tcp::socket socket1(io_service); 
    boost::asio::ip::tcp::resolver resolver(socket1.get_io_service()); 
    boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(), "9999"); 
    boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query); 
    boost::asio::connect(socket1, iterator); 
    boost::system::error_code error_code; 

    read(socket1, error_code); 
    write(socket1, error_code); 
    io_service.run(); 
    return 0; 
} 

Und das ist Simple Server-Programm:

#include <iostream> 
#include <boost/asio.hpp> 

void handler(boost::system::error_code &error_code, size_t size) 
{ 
} 

void read(boost::asio::ip::tcp::socket &socket1, boost::system::error_code error_code) 
{ 
    boost::asio::streambuf streambuf; 
    boost::asio::read(socket1, streambuf, error_code); 

    std::istream streambuf1(&streambuf); 
    std::string string; 
    streambuf1 >> string; 
    std::cout << string << std::endl; 
} 

void write(boost::asio::ip::tcp::socket &socket1, boost::system::error_code error_code) 
{ 
    std::string string("hello"); 
    boost::asio::write(socket1, boost::asio::buffer(string), error_code); 
} 

int main() 
{ 
    boost::asio::io_service io_service; 
    boost::asio::ip::tcp::socket socket1(io_service); 
    boost::asio::ip::tcp::acceptor acceptor(io_service, 
              boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 9999)); 
    boost::system::error_code error_code; 
    acceptor.accept(socket1, error_code); 
    if (error_code != nullptr) 
    { 
     std::cerr << error_code.message() << std::endl; 
    } 
    write(socket1, error_code); 
    read(socket1, error_code); 

    io_service.run(); 
    return 0; 
} 

Ist mein Weg falsch oder habe ich Gebrauch boost :: asio :: async_write() Verfahren zur Übertragung zurück und vierte Daten.

+0

Was genau ist das Problem? Stürzt es ab? Funktioniert etwas nicht? 'im race condition 'Wenn genau das passiert? Bitte geben Sie weitere Informationen an. – Blacktempel

+0

Das ist das Problem. Es stürzt nicht ab. Server und Client senden keine Daten an andere. Wenn ich Simplex-Kommunikation (Server zu Client || Client zu Server) festlege, werden Daten übertragen, aber wenn ich beides verwende (Schreib- und Lesefunktion), passiert nichts. Keine Daten senden oder empfangen auf beiden Seiten. Also das Problem. –

+0

Bitte denken Sie daran, [eine Antwort zu akzeptieren/zu verbessern, wenn Ihre Frage gelöst wurde.] (Https://stackoverflow.com/help/someone-answers) – Blacktempel

Antwort

0

Wenn Sie in die Dokumentation von boost::asio::streambuf schauen, können Sie bereits in der Examples Abteilung sehen, was Sie möglicherweise falsch machen.

Zunächst, Ihr Client verbindet sich mit ... welcher Adresse? 0.0.0.0? Sie sollten wirklich angeben, wo es sich verbinden soll. Das wirft einen Fehler,, da Sie den Fehlerfall bei Verbindung nicht behandeln. Vielleicht haben Sie nicht den richtigen Code zum Reproduzieren bereitgestellt?

Wenn Sie keine zufälligen Abstürze wünschen, behandeln Sie alle möglichen Fehlerfälle.
Boost hilft Ihnen bereits mit dem Fehler out-Parameter.

Jetzt, da Sie sich mit Ihrem Remote-Partner verbinden können, möchten Sie auch die gesendete Nachricht erhalten.

boost::asio::streambuf streambuf; 

//Reserve some bytes for data (here adjusted for your message 'hello') 
boost::asio::streambuf::mutable_buffers_type buf = streambuf.prepare(5); //Refer to documentation 
auto sizeReceived = boost::asio::read(socket1, buf, error_code); 
//Received bytes are 'committed' 
streambuf.commit(sizeReceived); 

std::istream streambuf1(&streambuf); 
std::string string; 
streambuf1 >> string; 
std::cout << string << std::endl; //'hello' 

Zusammen mit diesem, das ist der vollständige Code, den ich verwendet habe Ihre Probe zu testen (nicht die Basisklasse ausmacht):

class Runable 
{ 
public: 
    virtual void Run() = 0; 
}; 

class Client : public Runable 
{ 
public: 
    void Run() override 
    { 
     boost::asio::io_service io_service; 
     boost::asio::ip::tcp::socket socket1(io_service); 
     boost::asio::ip::tcp::resolver resolver(socket1.get_io_service()); 
     boost::asio::ip::tcp::resolver::query query("localhost", "9999"); //Specify where to connect 
     boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query); 
     boost::asio::connect(socket1, iterator); 
     boost::system::error_code error_code; 

     read(socket1, error_code); 
     write(socket1, error_code); 
     io_service.run(); 
    } 

private: 
    void read(boost::asio::ip::tcp::socket& socket1, boost::system::error_code error_code) 
    { 
     boost::asio::streambuf streambuf; 

     boost::asio::streambuf::mutable_buffers_type buf = streambuf.prepare(5); //Refer to documentation 
     auto sizeReceived = boost::asio::read(socket1, buf, error_code); 
     streambuf.commit(sizeReceived); 

     std::istream streambuf1(&streambuf); 
     std::string string; 
     streambuf1 >> string; 
     std::cout << __FUNCTION__ << " # " << string << std::endl; 
    } 

    void write(boost::asio::ip::tcp::socket& socket1, boost::system::error_code error_code) 
    { 
     std::string string("hello"); 
     boost::asio::write(socket1, boost::asio::buffer(string), error_code); 
    } 
}; 

class Server : public Runable 
{ 
public: 
    void Run() override 
    { 
     boost::asio::io_service io_service; 
     boost::asio::ip::tcp::socket socket1(io_service); 
     boost::asio::ip::tcp::acceptor acceptor(io_service, 
     boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 9999)); 
     boost::system::error_code error_code; 
     acceptor.accept(socket1, error_code); 
     if (error_code != nullptr) 
     { 
      std::cerr << error_code.message() << std::endl; 
     } 
     write(socket1, error_code); 
     read(socket1, error_code); 

     io_service.run(); 
    } 

private: 
    void read(boost::asio::ip::tcp::socket &socket1, boost::system::error_code error_code) 
    { 
     boost::asio::streambuf streambuf; 

     boost::asio::streambuf::mutable_buffers_type buf = streambuf.prepare(5); 
     auto sizeReceived = boost::asio::read(socket1, buf, error_code); 
     streambuf.commit(sizeReceived); 

     std::istream streambuf1(&streambuf); 
     std::string string; 
     streambuf1 >> string; 
     std::cout << __FUNCTION__ << " # " << string << std::endl; 
    } 

    void write(boost::asio::ip::tcp::socket &socket1, boost::system::error_code error_code) 
    { 
     std::string string("hello"); 
     boost::asio::write(socket1, boost::asio::buffer(string), error_code); 
    } 
}; 

int wmain(int argv, wchar_t **args) 
{ 
    std::thread st = std::thread([]() { Server s; s.Run(); }); 
    std::thread ct = std::thread([]() { std::this_thread::sleep_for(std::chrono::milliseconds(100)); Client c; c.Run(); }); 

    st.join(); 
    ct.join(); 

    return 0; 
} 

Wo ist der Ausgang :

Output

Bitte beachten Sie auch, Das boost::asio::read wird nicht zurückgegeben, wenn der Puffer nicht voll ist.

+0

Beachten Sie, dass dies nur ein schneller Test ist. Sie müssen sicherstellen, dass der Server eine Verbindung akzeptiert, bevor der Aufruf von "connect" auf der Clientseite erfolgt. (Hier mit einem Schlaf auf dem aktuellen Thread) – Blacktempel