<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Legacy Software - Seriell durch boost::asio tcp&#x2F;ip ersetzen]]></title><description><![CDATA[<p>ich versuche gerade eine alte Software mit seriellen Geräte wieder zum laufen zu bekommen - die Geräte fehlen mir - aber ich habe eine TCP/IP basierte Simulation welche exakt die Protokolle unterstützt</p>
<p>Es gibt RS232 auf TCP/IP Mapper - aber die freien Varianten sind zu stark begrenzt - ich brauch &gt;15 Ports</p>
<p>Konkret habe ich 3 Funktionen in der alten Software die ich per #define auf<br />
asio-TCP/IP-Varianten umbiege (damit ich nicht die ganze Protokoll-Verarbeitung anfassen muss - möglichst wenig Änderungen an der alten Software ist mein Ziel)</p>
<p>1. serial_port::read(buffer, buffer_size, read_size)<br />
Blockiert (sehr sehr sehr kurz) und liefert einfach nur was auf der seriellen Schnittstelle verfuegbar ist<br />
(asio/socket -&gt; async_receive?)</p>
<p>2. serial_port::read_timeout(buffer, read_size, timeout)<br />
Blockiert (maximal mit timeout) und wartet auf die size an Daten<br />
(asio/socket -&gt; async_read_some?)</p>
<p>3. serial_port::write_timeout(buffer, write_size)<br />
Blockiert (maximal mit timeout) bis bytes geschrieben<br />
(asio/socket -&gt; async_write_some?)</p>
<p>wie koennte ich die am besten mit asio als Client nachbauen - hat jemand Tipps?<br />
ich orientiere mich dabei an dem <a href="https://github.com/chriskohlhoff/asio/blob/master/asio/src/examples/cpp03/timeouts/blocking_tcp_client.cpp" rel="nofollow">https://github.com/chriskohlhoff/asio/blob/master/asio/src/examples/cpp03/timeouts/blocking_tcp_client.cpp</a> Beispiel für die Timeouts</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/339063/legacy-software-seriell-durch-boost-asio-tcp-ip-ersetzen</link><generator>RSS for Node</generator><lastBuildDate>Sun, 12 Apr 2026 11:18:08 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/339063.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 31 Jul 2016 14:44:47 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Legacy Software - Seriell durch boost::asio tcp&#x2F;ip ersetzen on Sun, 31 Jul 2016 14:44:47 GMT]]></title><description><![CDATA[<p>ich versuche gerade eine alte Software mit seriellen Geräte wieder zum laufen zu bekommen - die Geräte fehlen mir - aber ich habe eine TCP/IP basierte Simulation welche exakt die Protokolle unterstützt</p>
<p>Es gibt RS232 auf TCP/IP Mapper - aber die freien Varianten sind zu stark begrenzt - ich brauch &gt;15 Ports</p>
<p>Konkret habe ich 3 Funktionen in der alten Software die ich per #define auf<br />
asio-TCP/IP-Varianten umbiege (damit ich nicht die ganze Protokoll-Verarbeitung anfassen muss - möglichst wenig Änderungen an der alten Software ist mein Ziel)</p>
<p>1. serial_port::read(buffer, buffer_size, read_size)<br />
Blockiert (sehr sehr sehr kurz) und liefert einfach nur was auf der seriellen Schnittstelle verfuegbar ist<br />
(asio/socket -&gt; async_receive?)</p>
<p>2. serial_port::read_timeout(buffer, read_size, timeout)<br />
Blockiert (maximal mit timeout) und wartet auf die size an Daten<br />
(asio/socket -&gt; async_read_some?)</p>
<p>3. serial_port::write_timeout(buffer, write_size)<br />
Blockiert (maximal mit timeout) bis bytes geschrieben<br />
(asio/socket -&gt; async_write_some?)</p>
<p>wie koennte ich die am besten mit asio als Client nachbauen - hat jemand Tipps?<br />
ich orientiere mich dabei an dem <a href="https://github.com/chriskohlhoff/asio/blob/master/asio/src/examples/cpp03/timeouts/blocking_tcp_client.cpp" rel="nofollow">https://github.com/chriskohlhoff/asio/blob/master/asio/src/examples/cpp03/timeouts/blocking_tcp_client.cpp</a> Beispiel für die Timeouts</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2504100</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2504100</guid><dc:creator><![CDATA[Gast3]]></dc:creator><pubDate>Sun, 31 Jul 2016 14:44:47 GMT</pubDate></item><item><title><![CDATA[Reply to Legacy Software - Seriell durch boost::asio tcp&#x2F;ip ersetzen on Sun, 31 Jul 2016 15:39:17 GMT]]></title><description><![CDATA[<p>ist fuer VS2010/C++03, Boost 1.61.0 und es ist nur wichtig das die Timesouts auch anschlagen - ob die Kommunikation schneller oder langsamer abläuft ist nicht relevant</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2504110</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2504110</guid><dc:creator><![CDATA[Gast3]]></dc:creator><pubDate>Sun, 31 Jul 2016 15:39:17 GMT</pubDate></item><item><title><![CDATA[Reply to Legacy Software - Seriell durch boost::asio tcp&#x2F;ip ersetzen on Sun, 31 Jul 2016 19:17:03 GMT]]></title><description><![CDATA[<p>Ich baue jetzt erstmal ein verwertbares Beispiel und Frage dann noch mal später</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2504155</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2504155</guid><dc:creator><![CDATA[Gast3]]></dc:creator><pubDate>Sun, 31 Jul 2016 19:17:03 GMT</pubDate></item><item><title><![CDATA[Reply to Legacy Software - Seriell durch boost::asio tcp&#x2F;ip ersetzen on Mon, 01 Aug 2016 04:32:37 GMT]]></title><description><![CDATA[<p>VS2010, C++03, Boost 1.61.0<br />
basiert auf: <a href="https://github.com/chriskohlhoff/asio/blob/master/asio/src/examples/cpp03/timeouts/blocking_tcp_client.cpp" rel="nofollow">https://github.com/chriskohlhoff/asio/blob/master/asio/src/examples/cpp03/timeouts/blocking_tcp_client.cpp</a></p>
<p>die Routinen<br />
1. write_n_timeout<br />
2. read_available<br />
3. read_n_with_timeout</p>
<p>Verhalten sich mal so wie ich das gerne hätte - aber:<br />
-die Fehlerfälle werde noch nicht &quot;sauber&quot; mit return-Code (weil die alten C/C++-Schnittstellen so sind) behandelt (wie komme ich da richtig drann?)<br />
-ich bin mir mit den boost::lambdas oder handlern unsicher - ist das richtig so oder geht das mit weniger Code/sauberer<br />
-ich bin bei den async_write/read/receive(mit den cancel) nicht 100% sicher ob das die richtigen Funktionen fuer mich sind</p>
<p>Fragen sind mit &quot;Frage:&quot; markiert</p>
<p>zum testen benutzte ich Hercules: <a href="http://www.hw-group.com/products/hercules/index_de.html" rel="nofollow">http://www.hw-group.com/products/hercules/index_de.html</a></p>
<pre><code>#include &lt;boost/asio/connect.hpp&gt;
#include &lt;boost/asio/deadline_timer.hpp&gt;
#include &lt;boost/asio/io_service.hpp&gt;
#include &lt;boost/asio/ip/tcp.hpp&gt;
#include &lt;boost/asio/streambuf.hpp&gt;
#include &lt;boost/system/system_error.hpp&gt;
#include &lt;boost/asio/write.hpp&gt;
#include &lt;boost/asio/read.hpp&gt;
#include &lt;boost/bind/bind.hpp&gt;
#include &lt;boost/asio/placeholders.hpp&gt;
#include &lt;cstdlib&gt;
#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;boost/lambda/bind.hpp&gt;
#include &lt;boost/lambda/lambda.hpp&gt;

using boost::asio::deadline_timer;
using boost::asio::ip::tcp;
using boost::lambda::bind;
using boost::lambda::var;
using boost::lambda::_1;

class client
{
public:
  client(): socket_(io_service_), deadline_(io_service_)
  {
    deadline_.expires_at(boost::posix_time::pos_infin);
    check_deadline();
  }

  void connect(const std::string&amp; host, const std::string&amp; service, boost::posix_time::time_duration timeout)
  {
    tcp::resolver::query query(host, service);
    tcp::resolver::iterator iter = tcp::resolver(io_service_).resolve(query);

    deadline_.expires_from_now(timeout);

    boost::system::error_code ec = boost::asio::error::would_block;

    boost::asio::async_connect(socket_, iter, var(ec) = _1);

    // Block until the asynchronous operation has completed.
    do
    {
      io_service_.run_one(); 
    }
    while (ec == boost::asio::error::would_block);

    if (ec || !socket_.is_open())
    {
      throw boost::system::system_error(ec ? ec : boost::asio::error::operation_aborted);
    }
  }

  //warte auf n bytes bis zum timeout
  int read_n_with_timeout(void* p_data, size_t p_size, boost::posix_time::time_duration timeout)
  {
    deadline_.expires_from_now(timeout);

    boost::system::error_code ec = boost::asio::error::would_block;

    boost::asio::async_read(socket_, boost::asio::buffer(p_data, p_size), var(ec) = _1); // async - fuer den timeout  

    // Block until the asynchronous operation has completed.
    do
    { 
      io_service_.run_one(); 
    }
    while (ec == boost::asio::error::would_block);

    if (ec)
    {
      //throw boost::system::system_error(ec);
      return -1;
    }

    //FRAGE: im Timeoutfall kommt &quot;Die Netzwerkverbindung wurde durch das lokale System getrennt&quot; als Exception meldung - kann ich damit sauber einen Timeout erkennen?

    return 0; // 0 = OK, &lt;0 = Fehler, -1 = TIMEOUT
  }

  void read_available_handler(const boost::system::error_code&amp; error, std::size_t bytes_transferred)
  {
    if(!error)
    {
      printf(&quot;read_available_handler: %u\n&quot;, bytes_transferred);
      int brk = 1;
    }
    else if(error == boost::asio::error::operation_aborted)
    {
      //wenn keine Daten + cancel()
      printf(&quot;read_handler error: boost::asio::error::operation_aborted\n&quot;);
      assert(bytes_transferred == 0);
    }
    else
    {
      printf(&quot;read_available_handler error: %s\n&quot;, error.message().c_str());
      assert(false);
    }
  }

  //lese was da ist - 0-n bytes ohne timeout da nicht blockierend
  int read_available(void* p_data, size_t p_size)
  {
    boost::system::error_code ec;// = boost::asio::error::would_block;

    //FRAGE: wie kann man das mit boost::lambda - oder eben C++03 konform schreiben ohne den read_available_handler?
    socket_.async_receive(boost::asio::buffer(p_data, p_size), boost::bind(&amp;client::read_available_handler, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); // async - fuer den timeout  

    //hier will auch jemand 0-n bytes lesen - eben was da ist
    //http://stackoverflow.com/questions/31939843/boostasioasync-receive-and-0-bytes-in-socket 
    socket_.cancel(); // abbrechen scheint hier die loesung zu sein um die gleiche semantic zu erreichen - es funktioniert auch, sieht aber komisch aus

    //FRAGE: ist das so richtig?
    //do
    //{
    io_service_.run_one(); 
    //}
    //while (ec == boost::asio::error::would_block);

    //FRAGE: wie komme ich hier an die transfered bytes?

    if (ec)
    {
      //throw boost::system::system_error(ec);
      return -1;
    }

    return 0; // 0-n byte gelesen, &lt;0 = FEHLER
  }

  //schreibe n bytes (mit timeout)
  int write_n_timeout(void* p_data, size_t p_size, boost::posix_time::time_duration timeout)
  {
    deadline_.expires_from_now(timeout);

    boost::system::error_code ec = boost::asio::error::would_block;

    boost::asio::async_write(socket_, boost::asio::buffer(p_data, p_size), var(ec) = _1);

    // Block until the asynchronous operation has completed.
    do
    { 
      io_service_.run_one(); 
    }
    while (ec == boost::asio::error::would_block);

    if (ec)
    {
      //throw boost::system::system_error(ec);
      return -1;
    }

    //Frage: wie den Timeout sauber erkennen?

    return 0; // 0 = OK, &lt;0 = Fehler, -1 = TIMEOUT
  }

private:
  void check_deadline()
  {
    if (deadline_.expires_at() &lt;= deadline_timer::traits_type::now())
    {
      boost::system::error_code ignored_ec;
      socket_.close(ignored_ec);

      deadline_.expires_at(boost::posix_time::pos_infin);
    }

    // Put the actor back to sleep.
    deadline_.async_wait(bind(&amp;client::check_deadline, this));
  }

  boost::asio::io_service io_service_;
  tcp::socket socket_;
  deadline_timer deadline_;
  boost::asio::streambuf input_buffer_;
};

//----------------------------------------------------------------------

int main(int argc, char* argv[])
{
  try
  {
    std::string host = &quot;localhost&quot;;
    std::string service = &quot;544&quot;;

    client c;
    c.connect(host, service, boost::posix_time::seconds(10));

    char buffer[10]={0};

    printf(&quot;write_n_timeout (schreibe n bytes (mit timeout))\n&quot;);
    c.write_n_timeout(buffer, sizeof(buffer), boost::posix_time::seconds(10));

    printf(&quot;read_available (lese was da ist - 0-n bytes ohne timeout da nicht blockierend)\n&quot;); // bei dieser implementierung bin ich mir total unsicher
    c.read_available(buffer, sizeof(buffer)); // hol was da ist - nicht blockierend und ohne timeout

    printf(&quot;read_n_with_timeout (warte auf n bytes bis zum timeout)\n&quot;);
    boost::posix_time::ptime time_sent = boost::posix_time::microsec_clock::universal_time();
    c.read_n_with_timeout(buffer, sizeof(buffer), boost::posix_time::seconds(10));
    boost::posix_time::ptime time_received = boost::posix_time::microsec_clock::universal_time();

    std::cout &lt;&lt; &quot;Round trip time: &quot;;
    std::cout &lt;&lt; (time_received - time_sent).total_microseconds();
    std::cout &lt;&lt; &quot; microseconds\n&quot;;
  }
  catch (std::exception&amp; e)
  {
    std::cerr &lt;&lt; &quot;Exception: &quot; &lt;&lt; e.what() &lt;&lt; &quot;\n&quot;;
  }

  return 0;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2504176</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2504176</guid><dc:creator><![CDATA[Gast3]]></dc:creator><pubDate>Mon, 01 Aug 2016 04:32:37 GMT</pubDate></item></channel></rss>