Boost logo

Boost Users :

Subject: Re: [Boost-users] [asio] Problem implementing a line-based protocol
From: Hannes Brandstätter-Müller (boost_at_[hidden])
Date: 2011-01-11 08:23:47


On Tue, Jan 11, 2011 at 14:09, Rutger ter Borg <rutger_at_[hidden]> wrote:

> On 01/11/2011 01:50 PM, Hannes Brandstätter-Müller wrote:
>
>>
>>
>> That I did not try, but I just tried another, simpler program that does
>> the communication the same way. It worked perfectly, and even showed the
>> buffer size to be bigger (as almost all the messages were sent
>> simultaneously) and they were processed line by line, as intended.
>>
>
> Could you provide example code?

   void start_read() {
      // Set a deadline for the read operation.
      m_input_deadline.expires_from_now(boost::posix_time::seconds(30));

      // Start an asynchronous operation to read a newline-delimited
message.
      logging::instance().log_debug("Starting Read", this);
      boost::asio::async_read_until(m_socket, m_input_buffer, '\n',
boost::bind(
            &birfh_ipc_session::handle_read, shared_from_this(), _1, _2));
   }

   void handle_read(const boost::system::error_code& ec, std::size_t size) {
      if (stopped()) {
         return;
      }

      if (!ec) {
         logging::instance().log_debug("Got Buffer Size: " +
base::as_string(m_input_buffer.size()), this);
         logging::instance().log_debug("Got Message Size: " +
base::as_string(size), this);
         // Extract the newline-delimited message from the buffer.
         std::string msg;
         std::istream is(&m_input_buffer);
         std::getline(is, msg);
         logging::instance().log_debug("Got Message Size (read): " +
base::as_string(msg.length()), this);

         if (!msg.empty()) {
            logging::instance().log_debug("Got Message: " + msg, this);
            m_message_queue.push_back(birfh_message(msg));
         } else {
            // We received a heartbeat message from the client. If there's
nothing
            // else being sent or ready to be sent, send a heartbeat right
back.
            logging::instance().log_debug("Heartbeat received", this);
            if (m_output_queue.empty()) {
               m_output_queue.push_back("\n");

               // Signal that the output queue contains messages. Modifying
the
               // expiry will wake the output actor, if it is waiting on the
timer.

m_non_empty_output_queue.expires_at(boost::posix_time::neg_infin);
            }
         }
         start_read();
      } else {
         m_message_queue.push_back(my_message(my_protocol::exception_tag,
false, ec.message()));
         stop();
      }
   }

Log file (this is how it should work, with the small test case):

Starting Read
Session started.
Got Buffer Size: 512
Got Message Size: 39
Got Message Size (read): 38
Got Message: LOGON_ALGO:0:birfh-hannes:1337:11626:1
Starting Read
Got Buffer Size: 473
Got Message Size: 200
Got Message Size (read): 199
Got Message: PARAMETERNAMES:0:22 serialization::archive 7 0 0 10 0 0 0 4
test 4 blub 4 test 4 blub 4 test 4 blub 4 test 4 blub 4 test 4 blub 4 test 4
blub 4 test 4 blub 4 test 4 blub 4 test 4 blub 4 test 4 blub:2
Starting Read
Got Buffer Size: 273
Got Message Size: 19
Got Message Size (read): 18
Got Message: JOBDONE:0:0:1337:3

This is what happens with the other program (again, log):

Starting Read
Session started.
Got Buffer Size: 39
Got Message Size: 39
Got Message Size (read): 38
Got Message: LOGON_ALGO:0:birfh-hannes:1337:12175:1
Starting Read
Got Buffer Size: 132
Got Message Size: 132
Got Message Size (read): 131
Got Message: METERNAMES:0:22 serialization::archive 7 0 0 5 0 0 0 6 InSize 4
5809 7 InCount 1 5 6 MaxMut 1 2 7 WinSize 2 20 7 GC-Cont 2 -1:2
Starting Read
Got Buffer Size: 19
Got Message Size: 19
Got Message Size (read): 18
Got Message: JOBDONE:0:0:1337:3

As you might notice, the PARAMETERNAMES is missing a "PARA"

Hannes



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net