Write a very simple time server as an example: when you connect up, the Server side provides you with a direct timeframe and then ends the connection. Event_init () represents the variable used by the initialization libevent. Event_set (&ev, S, Ev_read | Ev_persist, Connection_accept, &ev) puts s This File Description into the EV (the first parameter and the second parameter) and tells you to call when the event (Ev_read of the third argument) occurs Connec Tion_accept () (fourth parameter), the EV is dropped in as a parameter when calling (the fifth parameter). The ev_persist says that when the call goes in, don't take the event away (keep it in the event Queue), which can be compared to the code in the Connection_accept () internal registration Connection_time (). Event_add (&ev, NULL) registers the EV into the event queue, and the second parameter specifies the Timeout time, which is set to NULL to ignore the setting.
Note: This code from the network, although very rough, but the use of libevent has been clearly explained.
Attached source code:
Copy Code code as follows:
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <event.h>
#include <stdio.h>
#include <time.h>
void Connection_time (int fd, short event, struct event *arg)
{
Char buf[32];
struct TM T;
time_t now;
Time (&now);
Localtime_r (&now, &t);
Asctime_r (&t, buf);
Write (FD, buf, strlen (BUF));
Shutdown (FD, SHUT_RDWR);
Free (ARG);
}
void connection_accept (int fd, short event, void *arg)
{
/* For debugging * *
fprintf (stderr, "%s (): FD =%d, event =%d.\n", __func__, FD, event);
/* Accept a new connection. */
struct sockaddr_in s_in;
socklen_t len = sizeof (s_in);
int ns = Accept (FD, (struct sockaddr *) &s_in, &len);
if (ns < 0) {
Perror ("accept");
Return
}
/* Install time server. */
struct Event *ev = malloc (sizeof (struct event));
Event_set (EV, NS, Ev_write, (void *) connection_time, Ev);
Event_add (EV, NULL);
}
int main (void)
{
/* Request socket. */
int s = socket (pf_inet, sock_stream, 0);
if (s < 0) {
Perror ("socket");
Exit (1);
}
/* BIND () */
struct sockaddr_in s_in;
Bzero (&s_in, sizeof (s_in));
s_in.sin_family = af_inet;
S_in.sin_port = htons (7000);
S_IN.SIN_ADDR.S_ADDR = Inaddr_any;
if (Bind (s, (struct sockaddr *) &s_in, sizeof (s_in)) < 0) {
Perror ("bind");
Exit (1);
}
/* Listen () * *
if (Listen (S, 5) < 0) {
Perror ("Listen");
Exit (1);
}
/* Initial libevent. */
Event_init ();
/* Create event. */
struct event ev;
Event_set (&ev, S, Ev_read | Ev_persist, Connection_accept, &ev);
/* ADD event. */
Event_add (&ev, NULL);
Event_dispatch ();
return 0;
}
Writing nonblocking network program usually deals with buffering problems, but it's not easy to write, mainly because read () or recv () does not guarantee that a single line of weight can come in at one time.
In the libevent provide a very good Buffer Library can be used, complete instructions in the man event can be seen, the most commonly used should be Evbuffer_add (), Evbuffer_readline () the two functio N, other know existence is OK, need to see the detailed usage again.
The following directly provide LIBEVENT-BUFF.C as an example, compiled to see the results of the implementation, and then look back to the source code should have a feeling:
Copy Code code as follows:
#include <sys/time.h>
#include <event.h>
#include <stdio.h>
void Printbuf (struct evbuffer *evbuf)
{
for (;;) {
Char *buf = evbuffer_readline (EVBUF);
printf ("* buf =%p, the string = \" \e[1;33m%s\e[m\ "\ n", buf, BUF);
if (buf = NULL)
Break
Free (BUF);
}
}
int main (void)
{
struct Evbuffer *evbuf;
Evbuf = Evbuffer_new ();
if (evbuf = = NULL) {
fprintf (stderr, "%s (): Evbuffer_new () failed.\n", __func__);
Exit (1);
}
/* ADD "Gslin" into buffer. */
U_char *buf1 = "Gslin";
printf ("* Add \" \e[1;33m%s\e[m\ ". \ n", buf1);
Evbuffer_add (Evbuf, Buf1, strlen (BUF1));
Printbuf (EVBUF);
U_char *buf2 = "is Reading.\nand it at Home.\nlast.";
printf ("* Add \" \e[1;33m%s\e[m\ ". \ n", buf2);
Evbuffer_add (Evbuf, Buf2, strlen (BUF2));
Printbuf (EVBUF);
Evbuffer_free (EVBUF);
}
The final Event_dispatch () represents entering the event loop, which enters callback function execution when any File Description in the Queue occurs.