-2

I'm trying to get a packet from the client with boost::asio::async_read_until..

boost::asio::async_read_until(socket, buf, 0x78, boost::bind(&Session::ReadHandler, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));

The client send FE 42 54 89 7B 14 05 78 FE 42 55 89 7B 14 05 78 and with async_read_until i got FE 42 54 89 7B 14 05 78. Now, how can i get the second part of packet ? in some cases, the client concatenate 2 or more packets in one before of send to server..

I hope this is possible, thanks in advanced !

Edit 1 My Code

boost::asio::ip::tcp::socket socket;
boost::asio::streambuf buf;

void Session::Read()
{
    boost::asio::async_read_until(socket, buf, 0x78, boost::bind(&Session::ReadHandler, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}

void Session::ReadHandler(const boost::system::error_code &error, std::size_t bytes_transferred)
{
    if (!error)
    {
        boost::asio::streambuf::const_buffers_type data = buf.data();
        std::string packet(boost::asio::buffers_begin(data), boost::asio::buffers_end(data));
        buf.consume(buf.size());
    }
    else
    {
        socket.close();
    }
}
Tanner Sansbury
  • 51,153
  • 9
  • 112
  • 169
INIM
  • 55
  • 4
  • Please read the following help link on how to ask question in a way where people can help -- http://stackoverflow.com/help/mcve and http://stackoverflow.com/help/on-topic – Soren Jul 12 '14 at 02:39
  • since you mention packets and not streams of data, an `ip::udp::socket` does not meet the `AsyncReadStream` type requirements, so you cannot use `async_read_until`. – Sam Miller Jul 16 '14 at 01:01

1 Answers1

3

async_read_until does exactly what it says it does: retrieves the data until the condition is true, in your case, until 0x78 is retrieved.

If you want to get more data, execute another async_read_until on the same buffer.

If you're using UDP (so "packets" actually exist), then use something that works with packets, like async_receive_from

EDIT: looking at the code (which still isn't a compilable example), it needs to, at least, use bytes_transferred both to read data from the buffer and to consume away what was read, and it needs to execute another async_read_until before exiting.

Cubbi
  • 46,567
  • 13
  • 103
  • 169
  • Thanks for answer but i still don't understand how to solve the problem.. async_read_until works perfectly getting FE 42 54 89 7B 14 05 78.. Now the problem ! If i execute another async_read_until it doesn't get FE 42 55 89 7B 14 05 78 but skip this jumping to the next packet.. I don't know real size of packet because it always change and i don't know in what cases client add 2 packets in one.. I'm using TCP protocol. – INIM Jul 12 '14 at 03:33
  • 1
    @INIM Perhaps you want to modify your packets to include a flag indicating either more coming or that it is the last packet. Then do { read_until } while(packet.flag != LAST); – u8sand Jul 12 '14 at 04:22
  • Thanks but i think you haven't understood my problem.. This is the packet that client send http://i.imgur.com/Ss2UhZa.png/ and this is what async_read_until return **FF 16 D1 FA 7B 11 12 78** The part **FF 16 D1 0A 7A 12 78** is skipped.. Loop isn't a problem.. The problem is when i get more than 1 delimiter, async_read_until return only the first part.. Is there a method for parse the complete packet ? or need i get byte per byte and check it ? – INIM Jul 12 '14 at 15:51
  • 2
    @INIM sounds like a complete minimal example is in order. In my experience, async_read_until doesn't skip anything. – Cubbi Jul 12 '14 at 17:05
  • Then i don't know what is the problem because server continue to get packets but (how i already said 3 times) if in a packet there are more than 1 delimiter it get only the first part.. I added my current code in first post.. – INIM Jul 12 '14 at 17:24
  • @INIM follow Cubbi's advice, call `async_read_until` a second time. – Sam Miller Jul 16 '14 at 01:11
  • @Sam Miler i already done it but doesn't works.. – INIM Jul 19 '14 at 12:46
  • One important characteristic of async_read_until() is that it reads until the input _contains_ the specified content - crucially, this means it may read _more_ than the required content. So you need to (a) repeatedly examine the returned data for multiple sequences that satisfy your requirement, and (b) preserve any remaining data to prepend to subsequent read data. See [this question](http://stackoverflow.com/questions/3058589/boostasioasync-read-until-reads-all-data-instead-of-just-some) for more discussion. – Jeremy Jan 16 '17 at 09:46
  • @Jeremy (b) is right, updated this old answer to point out that the buffer has tbe be the same on the second call to async_read_until – Cubbi Jan 16 '17 at 15:19