You can do a couple of things: * you can hack up the serialisation and buffering stuff so yes, it injects that length value into an already-queued buffer; * you can use iovec style setups to populate the _rest_ of the buffer, then setup the header iovec with the type/length, then send the whole thing to bufferevent; * you can use a chunked encoding style stream block encoding from HTTP, where each chunk has a length prefixing it, but there's no global length for the whole object that's specified up front.
Adrian On 21 May 2013 11:35, Mark Marchukov <[email protected]> wrote: > I have a problem that should be fairly common for app-level protocol > implementations over libevent. I need to send a stream of messages of > different types and sizes over a TCP connection managed by a bufferevent. > The format of each message on the wire is <length><type><body>, where > <length> is a 4-byte length of the message, <type> is a single-byte message > type, <body> is the rest of the message. Every message object in my code > knows how to serialize itself into an evbuffer, calculating and returning > the length of serialized content in the process. However, the length of the > message must appear in the evbuffer *before* the body of message. What’s the > recommended way to do this with libevent 2.1? > > > > I do not want to require every message object to have a function that > returns <length> for that message, in addition to the serialization > function. This will increase code complexity, and will somewhat reduce its > efficiency, since for complex payloads calculating <length> may take about > as much CPU as actually serializing the message. So far I looked at the > following options: > > > > 1) evbuffer_reserve_space()/evbuffer_commit_space() looked promising, but > the docs say appending data to evbuffer may invalidate the pointers I get > back. Is it true even if I pass an iovec of size 1? > > 2) evbuffer_add_reference() will allocate a new chain, which seems too > expensive for reserving 5 bytes on the critical path > > 3) serializing <body> into a separate evbuffer, then adding it to the > bufferevent’s output buffer by reference also looks expensive for 5 bytes > > > > Ideally, what I need is evbuffer_[reserve/commit]_space() that gives me a > pointer to a small (5-bytes) reserved segment of evbuffer, which will remain > valid after one or more subsequent calls to evbuffer_add() that will > compose the body of message. > > > > -Mark *********************************************************************** To unsubscribe, send an e-mail to [email protected] with unsubscribe libevent-users in the body.
