Skip to content

Instantly share code, notes, and snippets.

@makerj
Created July 5, 2017 16:37
Show Gist options
  • Select an option

  • Save makerj/15e70d363f713d95ea6854d586d0cbb0 to your computer and use it in GitHub Desktop.

Select an option

Save makerj/15e70d363f713d95ea6854d586d0cbb0 to your computer and use it in GitHub Desktop.

Revisions

  1. makerj created this gist Jul 5, 2017.
    96 changes: 96 additions & 0 deletions epoll_example.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,96 @@
    #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;
    }