Re: [Libevent-users] Simple Echo server with libevent 2.0
On Mon, 2009-05-18 at 12:37 -0400, Nick Mathewson wrote: > On Mon, May 18, 2009 at 05:26:04PM +0200, q6Yr7e0o nIJDVMjC wrote: > > Hi, > > > > > > can somebody guide me how to write a simple echo server using libevent 2.0? > > I've read into the sources of libevent (especially http.c) because i wanted > > to know how to bind to a socket, accept new connections and read/write async > > to the network. > > > > But there are so many interal functions (like bind_socket bind_socket_ai) > > which i have to copy (?) in order to bind to a socket that i think i got > > something wrong. > > I wouldn't look to http.c for examples; it was originally written for > a much older version of the API, and though it has been updated since > then, there are still a fair number of new interfaces that it isn't > using yet. > > For one example of how to use the 2.0.1-alpha API, you could have a > look at chapter 1 of > http://www.wangafu.net/~nickm/libevent-book/ . > > That's still a pretty ungainly way to do a server, though. In > 2.0.2-alpha, there will be a new "evconnlistener" API to wrap most of > the busywork of listening for new connections. I've attacked a quick > echo server written with it to this email. [It works for me on Linux; > haven't tested it anywhere else.] > > I hope we can get Libevent 2.0.2-alpha released this week. Until > then, you can use subversion to fetch the latest code from the > repository at > >https://levent.svn.sourceforge.net/svnroot/levent/trunk/libevent > > yrs, Thanks for everyone's work on libevent, and also Nick's new libevent-book pages (even I didn't read it yet since I am on some other projects). Personally I'd like to see some more sample code/apps coming with libevent release, instead of books or api docs in details. Code can tell all the truth to a coder and for a lazy coder as me, I like to copy and paste functions to my editor ;-) The samples may have some app frameworks (e.g. show how to fork and re-set event base, multi-thread), and some how-to in details (e.g. how to get connect event with libevent/eventbuffer, how to handle process runs out of number of fd...) Neils/Nick may build a list of samples then users like me could contribute the implement, then other users can use and improve the code. Cheers, Arthur ___ Libevent-users mailing list [email protected] http://monkeymail.org/mailman/listinfo/libevent-users
Re: [Libevent-users] Simple Echo server with libevent 2.0
On Mon, May 18, 2009 at 07:10:47PM +0200, q6Yr7e0o nIJDVMjC wrote: > Hi > > > > For one example of how to use the 2.0.1-alpha API, you could have a > > look at chapter 1 of > > ? ? ?http://www.wangafu.net/~nickm/libevent-book/ . > > Would it be possible to link that book on > http://monkey.org/~provos/libevent/ ? I've long googled for such > reference material but didn't find any Sorry! We'll put it up eventually (probably in the next week or two). It hasn't been called an official thing yet because it is very much a work in progress. (For instance, I haven't tried to compile any of the examples in the reference section yet. Also, some of the stuff that it documents only exists in Subversion.) [...] > > I hope we can get Libevent 2.0.2-alpha released this week. ?Until > > then, you can use subversion to fetch the latest code from the > > repository at > > > > ? https://levent.svn.sourceforge.net/svnroot/levent/trunk/libevent > > One think I don't understand about buffer events (I haven't read the > source yet): If i call > > struct evbuffer *input = bufferevent_get_input(bev); > > and then read the contents of input by calling bufferevent_read, is > there a way to not remove the data from the input buffer? First, you probably wouldn't grab the input evbuffer if you were using bufferevent_read(): bufferevent_read(be, b, n) is just an alias for evbuffer_remove(bufferevent_get_input(be), b, n). In 2.0.1-alpha, you can see the N bytes at the start of an evbuffer without removing them by calling evbuffer_pullup(). It isn't very efficient, though: see the documentation. The 2.0.2-alpha release will add an evbuffer_peek function to see the bytes in the evbuffer without copying them out, and without rearranging the internals of the evbuffer. If you're trying to reduce byte copies, it may do what you want. > Perhaps I > just want to look at it if it's enought to parse and if not wait for > another call of my echo_read_cb? Or do I have to read the input buffer > into another buffer to preserve it? > > If I have to read/write the buffers into each other, are the contents > copied each time? If you use evbuffer_add_buffer(), the contents aren't copied. If you use evbuffer_remove_buffer(), the contents are only copied to the extent they do not fall cleanly on a chunk boundary. yrs, -- Nick ___ Libevent-users mailing list [email protected] http://monkeymail.org/mailman/listinfo/libevent-users
Re: [Libevent-users] Simple Echo server with libevent 2.0
Hi > For one example of how to use the 2.0.1-alpha API, you could have a > look at chapter 1 of > http://www.wangafu.net/~nickm/libevent-book/ . Would it be possible to link that book on http://monkey.org/~provos/libevent/ ? I've long googled for such reference material but didn't find any > That's still a pretty ungainly way to do a server, though. In > 2.0.2-alpha, there will be a new "evconnlistener" API to wrap most of > the busywork of listening for new connections. I've attacked a quick > echo server written with it to this email. [It works for me on Linux; > haven't tested it anywhere else.] Ah cool thanks! I'll try it out. > I hope we can get Libevent 2.0.2-alpha released this week. Until > then, you can use subversion to fetch the latest code from the > repository at > > https://levent.svn.sourceforge.net/svnroot/levent/trunk/libevent One think I don't understand about buffer events (I haven't read the source yet): If i call struct evbuffer *input = bufferevent_get_input(bev); and then read the contents of input by calling bufferevent_read, is there a way to not remove the data from the input buffer? Perhaps I just want to look at it if it's enought to parse and if not wait for another call of my echo_read_cb? Or do I have to read the input buffer into another buffer to preserve it? If I have to read/write the buffers into each other, are the contents copied each time? ___ Libevent-users mailing list [email protected] http://monkeymail.org/mailman/listinfo/libevent-users
Re: [Libevent-users] Simple Echo server with libevent 2.0
On Mon, May 18, 2009 at 05:26:04PM +0200, q6Yr7e0o nIJDVMjC wrote:
> Hi,
>
>
> can somebody guide me how to write a simple echo server using libevent 2.0?
> I've read into the sources of libevent (especially http.c) because i wanted
> to know how to bind to a socket, accept new connections and read/write async
> to the network.
>
> But there are so many interal functions (like bind_socket bind_socket_ai)
> which i have to copy (?) in order to bind to a socket that i think i got
> something wrong.
I wouldn't look to http.c for examples; it was originally written for
a much older version of the API, and though it has been updated since
then, there are still a fair number of new interfaces that it isn't
using yet.
For one example of how to use the 2.0.1-alpha API, you could have a
look at chapter 1 of
http://www.wangafu.net/~nickm/libevent-book/ .
That's still a pretty ungainly way to do a server, though. In
2.0.2-alpha, there will be a new "evconnlistener" API to wrap most of
the busywork of listening for new connections. I've attacked a quick
echo server written with it to this email. [It works for me on Linux;
haven't tested it anywhere else.]
I hope we can get Libevent 2.0.2-alpha released this week. Until
then, you can use subversion to fetch the latest code from the
repository at
https://levent.svn.sourceforge.net/svnroot/levent/trunk/libevent
yrs,
--
Nick
#include
#include
#include
#include
#include
#include
#include
static void
echo_read_cb(struct bufferevent *bev, void *ctx)
{
/* This callback is invoked when there is data to read on bev. */
struct evbuffer *input = bufferevent_get_input(bev);
struct evbuffer *output = bufferevent_get_output(bev);
/* Copy all the data from the input buffer to the output buffer. */
evbuffer_add_buffer(output, input);
}
static void
echo_event_cb(struct bufferevent *bev, short events, void *ctx)
{
if (events & BEV_EVENT_ERROR)
perror("Error from bufferevent");
if (events & (BEV_EVENT_EOF | BEV_EVENT_ERROR)) {
bufferevent_free(bev);
}
}
static void
accept_conn_cb(struct evconnlistener *listener,
evutil_socket_t fd, struct sockaddr *address, int socklen,
void *ctx)
{
/* We got a new connection! Set up a bufferevent for it. */
struct event_base *base = evconnlistener_get_base(listener);
struct bufferevent *bev = bufferevent_socket_new(
base, fd, BEV_OPT_CLOSE_ON_FREE);
bufferevent_setcb(bev, echo_read_cb, NULL, echo_event_cb, NULL);
bufferevent_enable(bev, EV_READ|EV_WRITE);
}
int
main(int argc, char **argv)
{
struct event_base *base;
struct evconnlistener *listener;
struct sockaddr_in sin;
int port = 9876;
if (argc > 1) {
port = atoi(argv[1]);
}
if (port<=0 || port>65535) {
puts("Invalid port");
return 1;
}
base = event_base_new();
if (!base) {
puts("Couldn't open event base");
return 1;
}
/* Clear the sockaddr before using it, in case there are extra
* platform-specific fields that can mess us up. */
memset(&sin, 0, sizeof(sin));
/* This is an INET address */
sin.sin_family = AF_INET;
/* Listen on 0.0.0.0 */
sin.sin_addr.s_addr = htonl(0);
/* Listen on the given port. */
sin.sin_port = htons(port);
listener = evconnlistener_new_bind(base, accept_conn_cb, NULL,
LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, -1,
(struct sockaddr*)&sin, sizeof(sin));
if (!listener) {
perror("Couldn't create listener");
return 1;
}
event_base_dispatch(base);
return 0;
}
___
Libevent-users mailing list
[email protected]
http://monkeymail.org/mailman/listinfo/libevent-users
