Ich verwende BOOST für die asynchrone Kommunikation mit einer seriellen Schnittstelle. Ich kann die Ursache des Irrtums, mit dem ich konfrontiert bin, nicht genau bestimmen und würde mich über einige Hinweise freuen.Warum verursacht meine Implementierung von io_service :: run_one() einen unbestimmten Block und löst den Fehler # 125 aus?
std::string myclass::readStringUntil(const std::string& delim)
{
setupParameters=ReadSetupParameters(delim);
performReadSetup(setupParameters);
if(timeout!=posix_time::seconds(0)) timer.expires_from_now(timeout);
else timer.expires_from_now(posix_time::hours(100000));
timer.async_wait(boost::bind(&myclass::timeoutExpired,this,
asio::placeholders::error));
result=resultInProgress;
bytesTransferred=0;
for(;;)
{
io.run_one();
switch(result)
{
case resultSuccess:
{
timer.cancel();
bytesTransferred-=delim.size();//Don't count delim
istream is(&readData);
string result(bytesTransferred,'\0');//Alloc string
is.read(&result[0],bytesTransferred);//Fill values
is.ignore(delim.size());//Remove delimiter from stream
return result;
}
case resultTimeoutExpired:
port.cancel();
throw(timeout_exception("Timeout expired"));
cout<<"timeout on readuntill"<<endl;
case resultError:
timer.cancel();
port.cancel();
throw(boost::system::system_error(boost::system::error_code(),
"Error while reading"));
}
}
/////////////////////////////////////////////////////////////////////////////
void myclass::performReadSetup(const ReadSetupParameters& param)
{
if(param.fixedSize)
{
asio::async_read(port,asio::buffer(param.data,param.size),boost::bind(
&myclass::readCompleted,this,asio::placeholders::error,
asio::placeholders::bytes_transferred));
} else {
asio::async_read_until(port,readData,param.delim,boost::bind(
&myclass::readCompleted,this,asio::placeholders::error,
asio::placeholders::bytes_transferred));
}
}
/////////////////////////////////////////////////////////////////////////////
void myclass::timeoutExpired(const boost::system::error_code& error)
{
if(!error && result==resultInProgress) result=resultTimeoutExpired;
}
/////////////////////////////////////////////////////////////////////////////
void myclass::readCompleted(const boost::system::error_code& error,
const size_t bytesTransferred)
{
if(!error)
{
result=resultSuccess;
this->bytesTransferred=bytesTransferred;
return;
}
#ifdef _WIN32
if(error.value()==995) return; //Windows spits out error 995
#elif defined(__APPLE__)
if(error.value()==45)
{
//Bug on OS X, it might be necessary to repeat the setup
//http://osdir.com/ml/lib.boost.asio.user/2008-08/msg00004.html
performReadSetup(setupParameters);
return;
}
#else //Linux
if(error.value()==125) return; //Linux outputs error 125
#endif
result=resultError;
}
Ohne io.run_one(), gehe ich in eine Endlosschleife und nicht in den Schalter Fall.
Wie konnte ich meinen Code reparieren, so dass er aus dem unbestimmten Block herauskommt? Ich kann nicht bestätigen, aber ich denke, die run_one() verursacht einen Fehler # 125
Hey! Danke, dass du den Überblick behältst und mir hilfst! Ich entschuldige mich, wenn ich Ihnen einen unvollständigen Code übergeben habe. Es ist ein Ausschnitt aus dem Original. Ich bekomme "Fehler beim Lesen" auf meiner Konsole. Was hat io.run_one() in diesem Fall ausgeführt? Wie hat sich result = resultInProgress geändert? Für diejenigen, die in der Zukunft folgen, ist es eine Fortsetzung von dieser [Frage] (https://stackoverflow.com/questions/44429978/how-to-use-boostasioio-servicerun-one/44430221#44430221) –
Hast du gerade versucht zu debuggen? Oder fügen Sie ein Tracing in den Handlern 'readCompleted' oder' timeoutExpired' hinzu? Wie Sie sehen können, bekomme ich [nicht das spezifische Verhalten] (http://coliru.stacked-crooked.com/a/04ed1dcf723ff2b5). Achten Sie darauf, alle Hinweise unter meinem Antwortcode zu beachten. – sehe
Ich werde versuchen, es zu debuggen. Das Einrichten von SublimeGDB und der Projektdatei/Einstellungen ist wirklich sehr verwirrend, aber ich werde beharren. Vielen Dank für Ihre Hilfe –