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

Re: [Libevent-users] Read callback problem



2011/2/6 Gordiychuck Oleg <mybrokenbeat@xxxxxxxxx>:
>
>
> Начало переадресованного сообщения:
>
> От: Gordiychuck Oleg <mybrokenbeat@xxxxxxxxx>
> Дата: 7 лютого 2011 р. 00:04:43 GMT+02:00
> Кому: majordomo@xxxxxxxxxxxxx
> Тема: Read callback problem
>
> Hello!
>
> I have a simple network application with simple protocol over TCP\IP. The
> main idea of protocol is size+message model. So at first i'm sending size of
> message (coded in big-endian, first 4 bytes) than the whole message.
> I'm using event2 and read data from OnRead callback which i set and enabled
> to bufferevent with next code:
>
> static void OnRead(struct bufferevent *bev, void *user_data)
> {
> int buf_len = evbuffer_get_length(bufferevent_get_input(bev));
> ConnectionContext *ctx = user_data;
> uint8_t size_data[4],*data;
>
> printf("bytes avaliable this call: %d\n",buf_len); // always 18 bytes
>
> switch (ctx->state)
>        {
> case ReadSize:
> if (buf_len < 4)
> break;
> bufferevent_read(bev,size_data,4);
> ctx->size = get_be32(size_data);
> ctx->state = ReadCommand;
> break;
> case ReadCommand:
> if (buf_len<ctx->size)
> break;
> data = new uint8_t[ctx->size];
> bufferevent_read(bev,data,ctx->size);
> /// work with data
> delete[] data;
> break;
> default:
> //error handler
> }
> }
>
> Each time OnRead is called i don't know exactly how much bytes i will need
> to read. So if understand the mechanism of libevent right OnRead should be
> called each time there is at least one byte avaliable to read. When i try to
> send 18 bytes OnRead callback successfully called first time and ctx->state
> is set to ReadCommand, but callback is not calling second time, when there
> is 14 bytes avaliable! What am i doing wrong?

Check the documentation: the read callback is called _when more data
arrives_, not _whenever there is data_.  In other words, if there are
18 bytes on the input buffer, the read callback will be called.  If
you then remove only 4 bytes, the read callback won't get called again
until _more_ data arrives.

So you probably want to rewrite your code to look more like:

	switch (ctx->state)
       {
		case ReadSize:
			if (buf_len < 4)
				break;			
			bufferevent_read(bev,size_data,4);
			ctx->size = get_be32(size_data);
			ctx->state = ReadCommand;
                        // *** Fall through to the next case. ******
		case ReadCommand:
			if (buf_len<ctx->size)
				break;
			data = new uint8_t[ctx->size];
			bufferevent_read(bev,data,ctx->size);
			 /// work with data
			delete[] data;
	 	break;
		default:
			//error handler
	}
}
***********************************************************************
To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users    in the body.