[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [Libevent-users] socket message boundary problem



Hi Nick:

  Thank your for your advice.

Regards
YHM

On Thu, Jun 3, 2010 at 11:51 PM, Nick Mathewson <nickm@xxxxxxxxxxxxx> wrote:
> On Mon, May 31, 2010 at 1:14 PM, Hor Meng Yoong <yoonghm@xxxxxxxxx> 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 majordomo@xxxxxxxxxxxxx with
> unsubscribe libevent-users    in the body.
>
***********************************************************************
To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users    in the body.