Created
July 5, 2017 16:37
-
-
Save makerj/15e70d363f713d95ea6854d586d0cbb0 to your computer and use it in GitHub Desktop.
This file contains 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
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <unistd.h> | |
#include <sys/types.h> | |
#include <sys/socket.h> | |
#include <sys/epoll.h> | |
#include <sys/ioctl.h> | |
#include <netinet/in.h> | |
#include <arpa/inet.h> | |
#define MAX_EVENTS 1024 | |
#define RESPONSE_MESSAGE "epoll event bundle data" | |
typedef struct _Session Session; | |
typedef struct _Driver { | |
int (*read)(Session* session); | |
int (*write)(Session* session); | |
int (*close)(Session* session); | |
} Driver; | |
typedef struct _Session { | |
Driver* driver; | |
int fd; | |
void* data; | |
} Session; | |
Driver server_driver; | |
void loop(int epoll) { | |
struct epoll_event events[MAX_EVENTS] = {}; | |
while(1) { | |
int nevent = epoll_wait(epoll, events, MAX_EVENTS, 30); | |
if(nevent == -1) return; | |
for(int i = 0; i < nevent; ++i) { | |
struct epoll_event* e = &events[i]; | |
Session* session = e->data.ptr; | |
if(session->driver->read) | |
session->driver->read(session); | |
} | |
} | |
} | |
int server_read(Session* session) { | |
struct sockaddr_in client_addr = {}; | |
socklen_t client_addrlen = sizeof(client_addr); | |
int client = accept(session->fd, (struct sockaddr*)&client_addr, &client_addrlen); | |
if(client == -1) return 1; | |
ssize_t nwrite = write(client, session->data, sizeof(RESPONSE_MESSAGE)); | |
if(nwrite <= 0) return 2; | |
close(client); | |
return 0; | |
} | |
int main(int argc, char *argv[]) { | |
int error = 0; | |
int epoll = epoll_create1(0); | |
if(epoll == -1) return 1; | |
// Server Socket: Prepare socket | |
int server = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); | |
if(server == -1) return 2; | |
struct sockaddr_in server_addr = {}; | |
socklen_t server_addrlen = sizeof(server_addr); | |
server_addr.sin_family = AF_INET; | |
server_addr.sin_port = htons(61235); | |
server_addr.sin_addr.s_addr = htonl(INADDR_ANY); | |
error = bind(server, (const struct sockaddr*)&server_addr, server_addrlen); | |
if(error) return 3; | |
error = listen(server, 16); | |
if(error) return 4; | |
Session server_session = {}; | |
server_driver.read = server_read; | |
server_session.driver = &server_driver; | |
server_session.fd = server; | |
server_session.data = RESPONSE_MESSAGE; | |
// Server Socket: Register epoll event | |
struct epoll_event server_event = {}; | |
server_event.events = EPOLLIN; | |
server_event.data.ptr = &server_session; | |
error = epoll_ctl(epoll, EPOLL_CTL_ADD, server, &server_event); | |
if(error) return 5; | |
// Start main loop | |
loop(epoll); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment