Hi Nick: Thank your for your advice.
Regards YHM On Thu, Jun 3, 2010 at 11:51 PM, Nick Mathewson <ni...@freehaven.net> wrote: > On Mon, May 31, 2010 at 1:14 PM, Hor Meng Yoong <yoon...@gmail.com> wrote: >> Hi: >> >> I am using libevent2. Is that a wrapper function/library to send and >> receive fixed length message, or variable length message with message length >> embedded in the first 2 bytes with libevent2? Thank > > Got all three of your messages. No need to send so many! > > There's no built-in function to do this, but it's very easy to do with > bufferevents. Here's some example demo code to show you the general > idea of how it's done: > > > #include <event2/bufferevent.h> > #include <event2/buffer.h> > > #define MSG_LEN 512 > > int > send_fixed_msg(struct bufferevent *bev, const char *msg) > { > bufferevent_write(bev, msg, MSG_LEN); > return 0; > } > > void > fixed_msg_readcb(struct bufferevent *bev, void *ctx) > { > char msg_buf[MSG_LEN]; > struct evbuffer *inp = bufferevent_get_input(bev); > while (evbuffer_get_length(inp) >= MSG_LEN) { > evbuffer_remove(inp, msg_buf, MSG_LEN); > /* Here's where you add code to handle the contents of > * msg_buf */ > } > } > > void > setup_fixed_msg_bufferevent(struct bufferevent *bev) > { > /* Set up the read callback to be invoked when we have some bytes that > have arrived. In practice, you'd also want to set the other > callbacks, and maybe provide some data too. */ > bufferevent_setcb(bev, fixed_msg_readcb, NULL, NULL, NULL); > } > > > /* Now, variable-length messages. Let's assume that the message format > * is a two-byte length value encoded in big-endian (network) order, > * plus that number of bytes worth of message */ > int > send_var_msg(struct bufferevent *bev, const char *msg, int length) > { > ev_uint16_t len_encoded; > if (length < 0 || length > 65535) > return -1; > len_encoded = htons(length); > bufferevent_write(bev, &len_encoded, 2); > bufferevent_write(bev, msg, length); > return 0; > } > > void > var_msg_readcb(struct bufferevent *bev, void *ctx) > { > struct evbuffer *inp = bufferevent_get_input(bev); > char msg_buf[65536]; > ev_uint16_t len_encoded; > int msglen; > while (1) { > int len_in_buf = evbuffer_get_length(inp); > if (len_in_buf < 2) > return; > /* We have enough data to read a length field. For now, > * just inspect it but don't remove it. > */ > evbuffer_copyout(inp, &len_encoded, 2); > msglen = ntohs(len_encoded); > if (len_in_buf < 2 + msglen) { > /* The entire message hasn't arrived yet. */ > return; > } > /* The message is here; pull it out of the buffer. */ > evbuffer_drain(inp, 2); /*discard the length field */ > evbuffer_remove(inp, msg_buf, msglen); > > /* Here's where you add code to handle the contents of > * msg_buf */ > } > } > > void > setup_var_msg_bufferevent(struct bufferevent *bev) > { > /* Set up the read callback to be invoked when we have some bytes that > have arrived. In practice, you'd also want to set the other > callbacks, and maybe provide some data too. */ > bufferevent_setcb(bev, var_msg_readcb, NULL, NULL, NULL); > } > > > > Note that in practice you might want to use watermarks to avoid > extraneous calls to the _readcb functions. For more info on the > bufferevent API, check out chapter Ref6 of > http://www.wangafu.net/~nickm/libevent-book/ . > > hope this helps, > -- > Nick > *********************************************************************** > To unsubscribe, send an e-mail to majord...@freehaven.net with > unsubscribe libevent-users in the body. > *********************************************************************** To unsubscribe, send an e-mail to majord...@freehaven.net with unsubscribe libevent-users in the body.