Skip to content

Instantly share code, notes, and snippets.

@skihero
Created December 19, 2013 14:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save skihero/8039893 to your computer and use it in GitHub Desktop.
Save skihero/8039893 to your computer and use it in GitHub Desktop.
Re learning mode. A bit of play with epoll
/*
* Program to serve many client request without blocking
* using epoll
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/epoll.h>
#include <sys/types.h>
#include <netinet/in.h>
#define BUF_SIZE 500
#define MAX_EVENTS 10
int
main(int argc, char *argv[])
{
/* epoll specific */
struct epoll_event ev ;
struct epoll_event events[MAX_EVENTS] ; /* Store available events here */
int nfds ; /* No of fds ready for IO */
int epollfd ; /* epoll instance fd */
/* Socket specific declarations */
int my_socket ; /*Socket desc */
struct sockaddr_in in_name ; /* holds the sa_family, etc.. */
socklen_t in_name_len ; /* socket length */
unsigned short port = 12345; /* Location */
int bind_ret ; /* Bind() RC */
int bck_log = 5 ; /* Max pending connections in sockfd */
int listen_sock ;
int conn_sock; /* Accpeted connection desc */
int n = 0 ; /* Loop var */
/* Create a socket, bind and listen */
my_socket = socket(AF_INET, SOCK_STREAM, 0) ;
if (my_socket == -1 ) {
printf("socket error\n");
exit(1);
}
/* Define the name */
/* Check if sizeof on this gives us the right bytes */
memset(&in_name, 0 , sizeof(&in_name)) ;
in_name.sin_family = AF_INET;
in_name.sin_port = htons(port);
in_name.sin_addr.s_addr = INADDR_ANY ;
in_name_len = sizeof(struct sockaddr_in);
/* Bind the socket */
bind_ret = bind(my_socket, (struct sockaddr *) &in_name, in_name_len);
if (bind_ret == -1) {
printf("Bind error\n");
close(my_socket);
exit(1);
}
/* Listen */
printf("Listening to incoming requests\n");
fflush(stdout);
listen_sock = listen( my_socket, bck_log);
if (listen_sock) {
printf("listen error\n");
close(my_socket);
exit(1);
}
/* Setup an epoll instance */
epollfd = epoll_create(10);
if (epollfd == -1) {
perror("epoll_create");
exit(EXIT_FAILURE);
}
listen_sock = my_socket ;
/* Set the events to read */
ev.events = EPOLLIN; /* Set it for read operations */
ev.data.fd = listen_sock; /* Our listener name */
/* Register the target fd to the ep and associate event with the ep */
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_sock, &ev) == -1) {
perror("epoll_ctl: listen_sock");
exit(EXIT_FAILURE);
}
/* Loop forever */
for (;;) {
/* Wait for I/O event on the epfd */
nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1 );
if (nfds == -1) {
perror("epoll_pwait");
exit(EXIT_FAILURE);
}
printf("No of nfds %d \n ", nfds );
fflush(stdout);
/* After timeout we have the ready count of descriptors */
/* Loop thru the I/O ready descriptors */
for (n = 0; n < nfds; ++n) {
/*Find the one we were listening */
/* This is found from the event data fd that we set using epoll_ctl earlier */
if (events[n].data.fd == listen_sock) {
/* If this is our incoming connection*/
/* Accept the connection */
conn_sock = accept(my_socket, (struct sockaddr *) &in_name, &in_name_len);
printf(" Listen event events[%d].data.fd : %d \n", n, events[n].data.fd ) ;
if (conn_sock == -1) {
perror("accept");
exit(EXIT_FAILURE);
}
//setnonblocking(conn_sock);
printf("non blocking goes here \n");
/* Set the events that we want to handle */
ev.events = EPOLLIN | EPOLLET ;
ev.data.fd = conn_sock ;
/* Add it to our event list, service it when ready */
if ( epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock, &ev) == -1 ) {
perror("epoll ctl : conn_sock " );
exit(EXIT_FAILURE);
}
}
else {
/* If any other in the event list */
/* Check the fd in the event struct and take action */
printf("This is the event that is not from listen connection \n");
printf("events[%d].data.fd : %d \n", n, events[n].data.fd ) ;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment