Skip to content

Instantly share code, notes, and snippets.

@nishidy
Last active August 29, 2015 14:19
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 nishidy/a46af988dc5bd02aa4d1 to your computer and use it in GitHub Desktop.
Save nishidy/a46af988dc5bd02aa4d1 to your computer and use it in GitHub Desktop.
epoll (Non Blocking I/O)
#include <stdio.h>
#include <stdlib.h>
#include <sys/epoll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#define CONCURRENT 10
int main(){
int listen_sock, conn_sock, epoll_fd;
struct epoll_event event;
struct epoll_event *events;
struct sockaddr_in server;
struct sockaddr_in client;
fd_set fds, _fds;
char rbuf[65535];
char sbuf[] = "Done.";
listen_sock = socket(AF_INET, SOCK_STREAM, 0);
if( listen_sock == -1 ){
fprintf(stderr, "socket() error [%d].", errno);
return -1;
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_port = htons(11111);
if( bind(listen_sock, (struct sockaddr *)&server, sizeof(server)) == -1 ){
fprintf(stderr, "bind() error [%d].", errno);
return -1;
}
int flags = fcntl( listen_sock, F_GETFL, 0 );
if( flags == -1 ){
fprintf(stderr,"fcntl error[%d].",errno);
return -1;
}
flags |= O_NONBLOCK;
if( fcntl( listen_sock, F_SETFL, flags ) == -1 ){
fprintf(stderr,"fcntl error[%d].",errno);
return -1;
}
if( listen(listen_sock, CONCURRENT) == -1 ){
fprintf(stderr, "listen() error [%d].", errno);
return -1;
}
epoll_fd = epoll_create1(0);
if( epoll_fd == -1 ){
fprintf(stderr,"epoll_create1 error [%d].",errno);
}
event.data.fd = listen_sock;
event.events = EPOLLIN | EPOLLET;
if( epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listen_sock, &event) == -1 ){
fprintf(stderr,"epoll_ctrl error [%d].",errno);
return -1;
}
events = (epoll_event *)calloc(CONCURRENT, sizeof(event));
int cnt=0;
int event_cnt=0;
while(1){
printf("Wait at epoll_wait #%d.\n", cnt);
event_cnt=epoll_wait(epoll_fd, events, CONCURRENT, -1);
int len, size;
for(int i=0; i<event_cnt; i++){
if( !(events[i].events & EPOLLIN) ){
fprintf(stderr, "epoll_wait error [%d].",errno);
return -1;
}else if( listen_sock == events[i].data.fd ){
printf("Connect request(s) received.\n");
while(1){
len = sizeof(client);
conn_sock = accept(listen_sock, (struct sockaddr *)&client, (socklen_t *)&len);
if( conn_sock == -1 ){
if ( errno == EAGAIN ){
printf("Processed all incoming connections @ %d.\n", listen_sock);
break;
}else{
fprintf(stderr, "accept error [%d].", errno);
return -1;
}
}
flags = fcntl( conn_sock, F_GETFL, 0 );
if( flags == -1 ){
fprintf(stderr,"fcntl error[%d].",errno);
return -1;
}
flags |= O_NONBLOCK;
if( fcntl( conn_sock, F_SETFL, flags ) == -1 ){
fprintf(stderr,"fcntl error[%d].",errno);
return -1;
}
event.data.fd = conn_sock;
event.events = EPOLLIN | EPOLLET;
if( epoll_ctl( epoll_fd, EPOLL_CTL_ADD, conn_sock, &event) == -1 ){
fprintf(stderr, "epoll_ctl error [%d].",errno);
return -1;
}
printf("Added %d to epoll instance.\n",conn_sock);
}
}else{
while(1){
printf("Send request received from %d.\n",events[i].data.fd);
memset(rbuf, 0, sizeof(rbuf));
size = recv( events[i].data.fd, rbuf, sizeof(rbuf), 0);
printf("Received data size %d byte.\n",size);
if( size == -1 ){
if ( errno == EAGAIN ){
printf("Processed all incoming connections @ %d.\n",events[i].data.fd);
break;
}else{
fprintf(stderr, "recv error [%d].", errno);
return -1;
}
}else if( size == 0 ){
printf("Closed by %d.\n",events[i].data.fd);
//shutdown(events[i].data.fd, 2);
close(events[i].data.fd);
break;
}else{
printf("%s\n", rbuf);
send(events[i].data.fd, sbuf, sizeof(sbuf), 0);
}
}
}
}
sleep(5);
cnt++;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment