Last active
August 29, 2015 14:07
-
-
Save ixn/cc28d3173def798e7b17 to your computer and use it in GitHub Desktop.
Hello World in C use Libevent
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
This exmple program provides a trivial server program that listens for TCP | |
connections on port 9995. When they arrive, it writes a short message to | |
each client connection, and closes each connection once it is flushed. | |
Where possible, it exits cleanly in response to a SIGINT (ctrl-c). | |
*/ | |
/* Deklarasi lib standar yang digunakan */ | |
#include <string.h> | |
#include <errno.h> | |
#include <stdio.h> | |
#include <signal.h> | |
#ifndef WIN32 | |
#include <netinet/in.h> | |
# ifdef _XOPEN_SOURCE_EXTENDED | |
# include <arpa/inet.h> | |
# endif | |
#include <sys/socket.h> | |
#endif | |
/* Deklarasi lib tambahan dari libevent */ | |
#include <event2/bufferevent.h> | |
#include <event2/buffer.h> | |
#include <event2/listener.h> | |
#include <event2/util.h> | |
#include <event2/event.h> | |
/* Membuat variabel MESSAGE dengan value Hello World */ | |
static const char MESSAGE[] = “Hello, World!\n”; | |
/* Membuat variabel Port yang akan digunakan dengan value 9995 */ | |
static const int PORT = 9995; | |
/* Variabel koneksi yang wajib digunakan untuk menghubungkan C dengan socket */ | |
static void listener_cb(struct evconnlistener *, evutil_socket_t, | |
struct sockaddr *, int socklen, void *); | |
static void conn_writecb(struct bufferevent *, void *); | |
static void conn_eventcb(struct bufferevent *, short, void *); | |
static void signal_cb(evutil_socket_t, short, void *); | |
int | |
main(int argc, char **argv) | |
{ | |
struct event_base *base; | |
struct evconnlistener *listener; | |
struct event *signal_event; | |
struct sockaddr_in sin; | |
#ifdef WIN32 | |
WSADATA wsa_data; | |
WSAStartup(0x0201, &wsa_data); | |
#endif | |
base = event_base_new(); | |
if (!base) { | |
fprintf(stderr, “Could not initialize libevent!\n”); | |
return 1; | |
} | |
memset(&sin, 0, sizeof(sin)); | |
sin.sin_family = AF_INET; | |
sin.sin_port = htons(PORT); | |
listener = evconnlistener_new_bind(base, listener_cb, (void *)base, | |
LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_FREE, -1, | |
(struct sockaddr*)&sin, | |
sizeof(sin)); | |
if (!listener) { | |
fprintf(stderr, “Could not create a listener!\n”); | |
return 1; | |
} | |
signal_event = evsignal_new(base, SIGINT, signal_cb, (void *)base); | |
if (!signal_event || event_add(signal_event, NULL)<0) { | |
fprintf(stderr, “Could not create/add a signal event!\n”); | |
return 1; | |
} | |
event_base_dispatch(base); | |
evconnlistener_free(listener); | |
event_free(signal_event); | |
event_base_free(base); | |
printf(“done\n”); | |
return 0; | |
} | |
static void | |
listener_cb(struct evconnlistener *listener, evutil_socket_t fd, | |
struct sockaddr *sa, int socklen, void *user_data) | |
{ | |
struct event_base *base = user_data; | |
struct bufferevent *bev; | |
bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); | |
if (!bev) { | |
fprintf(stderr, “Error constructing bufferevent!”); | |
event_base_loopbreak(base); | |
return; | |
} | |
/* Mengkatifkan fungsi pemanggilan, pengaktifan dan penulisan HTTP */ | |
bufferevent_setcb(bev, NULL, conn_writecb, conn_eventcb, NULL); | |
bufferevent_enable(bev, EV_WRITE); | |
bufferevent_disable(bev, EV_READ); | |
bufferevent_write(bev, MESSAGE, strlen(MESSAGE)); | |
} | |
static void | |
conn_writecb(struct bufferevent *bev, void *user_data) | |
{ | |
struct evbuffer *output = bufferevent_get_output(bev); | |
if (evbuffer_get_length(output) == 0) { | |
printf(“flushed answer\n”); | |
bufferevent_free(bev); | |
} | |
} | |
static void | |
conn_eventcb(struct bufferevent *bev, short events, void *user_data) | |
{ | |
if (events & BEV_EVENT_EOF) { | |
printf(“Connection closed.\n”); | |
} else if (events & BEV_EVENT_ERROR) { | |
printf(“Got an error on the connection: %s\n”, | |
strerror(errno));/*XXX win32*/ | |
} | |
/* None of the other events can happen here, since we haven’t enabled | |
* timeouts */ | |
bufferevent_free(bev); | |
} | |
static void | |
signal_cb(evutil_socket_t sig, short events, void *user_data) | |
{ | |
struct event_base *base = user_data; | |
struct timeval delay = { 2, 0 }; | |
printf(“Caught an interrupt signal; exiting cleanly in two seconds.\n”); | |
event_base_loopexit(base, &delay); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment