Skip to content

Commit

Permalink
How Sexy Is My Epoll Server
Browse files Browse the repository at this point in the history
  • Loading branch information
Martiusweb committed Feb 16, 2011
1 parent 1374292 commit 607ba96
Showing 1 changed file with 38 additions and 14 deletions.
52 changes: 38 additions & 14 deletions code/epoll_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,23 @@
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <sys/epoll.h>

/*** Configuration ***/
/* Server port */
static const uint16_t SERVER_PORT = 7000;
static const uint16_t SERVER_PORT = 7001;
/* Max clients */
static const int MAX_CLIENTS = 1000;
/* Max epoll events that can be caught
* TODO explain how to choose this value (currently *rand*) */
static const MAX_EPOLL_EVENTS = 64;
static const int MAX_EPOLL_EVENTS = 64;
/* Max epoll events processed per loop
* TODO explain this one too */
static const MAX_EPOLL_EVENTS_PER_LOOP = 16;
static const int MAX_EPOLL_EVENTS_PER_LOOP = 16;

/**
* Sets the socket described by fd as non-blocking.
Expand Down Expand Up @@ -91,17 +92,19 @@ static int create_server(uint16_t port, int max_clients)
* Add the socket to the I/O descriptors watched by our epoll structure.
* @param epollq epoll file descriptor
* @param socket_server server socket to watch
* @param mode epoll_ctl mode (EPOLL_CTL_ADD or EPOLL_CTL_MOD)
* Returns the epoll fd or -1 in case of error
*/
static int epoll_watch_server(int epollq, int socket_server)
static int epoll_watch_in(int epollq, int socket_server, int mode =
EPOLL_CTL_ADD)
{
struct epoll_event event;

/* Nb events EPOLLHUP and EPOLLERR are impicitly set */
event.events = EPOLLIN /* ready to read */;
event.data.fd = socket_server;

if(epoll_ctl(epollq, EPOLL_CTL_ADD, socket_server, &event) == -1) {
if(epoll_ctl(epollq, mode, socket_server, &event) == -1) {
return -1;
}

Expand All @@ -112,17 +115,19 @@ static int epoll_watch_server(int epollq, int socket_server)
* Add the socket to the I/O descriptors watched by our epoll structure.
* @param epollq epoll file descriptor
* @param socket_client client socket to watch
* @param mode epoll_ctl mode (EPOLL_CTL_ADD or EPOLL_CTL_MOD)
* Returns the epoll fd or -1 in case of error
*/
static int epoll_watch_client(int epollq, int socket_client)
static int epoll_watch_inout(int epollq, int socket_client, int mode =
EPOLL_CTL_ADD)
{
struct epoll_event event;

/* @see epoll_watch_server */
/* @see epoll_watch_in */
event.events = EPOLLIN | EPOLLOUT;
event.data.fd = socket_client;

if(epoll_ctl(epollq, EPOLL_CTL_ADD, socket_client, &event) == -1) {
if(epoll_ctl(epollq, mode, socket_client, &event) == -1) {
return -1;
}
return epollq;
Expand Down Expand Up @@ -150,11 +155,16 @@ static int epoll_unwatch(int epollq, int fd)
int main()
{
int socket_server = 0, socket_client = 0, epollq = 0, nb_events = 0,
addr_ln = 0, i = 0;
read = 0, i = 0;
socklen_t addr_ln = 0;
struct epoll_event epoll_event, events[MAX_EPOLL_EVENTS_PER_LOOP];
/* TODO it may be good to keep the user address somewhere... */
struct sockaddr_in addr_client = {0};

/* For testing purpose : implementation quite stupid of a dummy protocol */
int BUFFER_SIZE = 256;
char buffer[BUFFER_SIZE];

if((socket_server = create_server(SERVER_PORT, MAX_CLIENTS)) == -1) {
perror("Can not create or bind or listen on the server socket ");
exit(errno);
Expand All @@ -168,7 +178,7 @@ int main()
}
printf("Epoll ready to wait for %d events !\n", MAX_EPOLL_EVENTS);

if(epoll_watch_server(epollq, socket_server) == -1) {
if(epoll_watch_in(epollq, socket_server) == -1) {
close(epollq);
close(socket_server);
perror("Can not add the server socket file descriptor to epoll ");
Expand All @@ -186,26 +196,40 @@ int main()
/* error on a client socket */
if(events[i].data.fd != socket_server &&
(events[i].events & (EPOLLHUP|EPOLLERR))) {
perror("Connection with client closed\n");
epoll_unwatch(epollq, events[i].data.fd);
close(events[i].data.fd);
}
else if(events[i].data.fd == socket_server) {
else if(events[i].data.fd == socket_server && (events[i].events &
EPOLLIN)) {
if((socket_client = accept(socket_server, (struct sockaddr*)
&addr_client, &addr_ln)) > 0) {

if(socket_set_nonblocking(socket_client) == -1) {
close(socket_client);
perror("Can not set the client non blocking\n");
}
else if(epoll_watch_client(epollq, socket_client) == -1) {
else if(epoll_watch_in(epollq, socket_client) == -1) {
close(socket_client);
perror("Can not watch the client with epoll\n");
}
}
}
else {
/* manage_events(&(events[i])); */
printf("User Event !\n");
if(events[i].events & EPOLLIN) {
read = recv(events[i].data.fd, buffer, BUFFER_SIZE,
MSG_DONTWAIT);
epoll_watch_inout(epollq, events[i].data.fd,
EPOLL_CTL_MOD);
buffer[read] = 0;
printf("Read from socket \"%s\"\n", buffer);
}
if(events[i].events & EPOLLOUT) {
send(events[i].data.fd, "plop\n", 5,
MSG_DONTWAIT|MSG_NOSIGNAL);
epoll_unwatch(epollq, events[i].data.fd);
close(events[i].data.fd);
}
}
}
}
Expand Down

0 comments on commit 607ba96

Please sign in to comment.