Skip to content

Instantly share code, notes, and snippets.

@tokers
Created June 30, 2019 06:42
Show Gist options
  • Save tokers/acbe3016395edfbd62ac7f5fdf558943 to your computer and use it in GitHub Desktop.
Save tokers/acbe3016395edfbd62ac7f5fdf558943 to your computer and use it in GitHub Desktop.
epollrdhup
#include <stdio.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h> /* See NOTES */
#include <netinet/in.h>
#include <arpa/inet.h>
#define LISTEN_HOST "127.0.0.1"
#define LISTEN_PORT 13105
static void nonblocking(int fd)
{
int flags;
int n;
if (fcntl(fd, F_GETFL, &flags) < 0) {
printf("fcntl(): %s\n", strerror(errno));
exit(1);
}
flags |= O_NONBLOCK;
if (fcntl(fd, F_SETFL, flags) < 0) {
printf("fcntl(): %s\n", strerror(errno));
exit(1);
}
}
static void epoll_loop(int epoll_fd, int listen_fd)
{
struct epoll_event *events, *ev, tmp_event;;
struct sockaddr addr;
socklen_t len;
int i, fd;
char buf[1];
events = malloc(10 * sizeof(struct epoll_event));
memset(events, 0, 10 * sizeof(events));
if (events == NULL) {
printf("no memory\n");
exit(1);
}
for ( ;; ) {
int n = epoll_wait(epoll_fd, events, 10, -1);
if (n < 0) {
printf("epoll_wait(): %s\n", strerror(errno));
continue;
}
printf("n = %d\n", n);
for (i = 0; i < n; i++) {
ev = &events[i];
if ((ev->events & EPOLLIN)) {
if (ev->data.fd == listen_fd) {
len = sizeof(struct sockaddr);
fd = accept(listen_fd, &addr, &len);
if (fd < 0) {
printf("accept(): %s\n", strerror(errno));
continue;
}
nonblocking(fd);
memset(&tmp_event, 0, sizeof(struct epoll_event));
tmp_event.events = EPOLLIN|EPOLLRDHUP|EPOLLOUT|EPOLLERR|EPOLLHUP|EPOLLET;
tmp_event.data.fd = fd;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &tmp_event) < 0) {
printf("epoll_ctl(): %s\n", strerror(errno));
exit(1);
}
} else {
if (ev->events & EPOLLRDHUP) {
printf("client closed connection!\n");
}
int n = recv(ev->data.fd, buf, 1, MSG_PEEK);
if (n > 0) {
printf("rest %d\n", n);
continue;
}
}
}
}
}
}
int main() {
int epoll_fd;
int listen_fd;
struct sockaddr_in sock;
struct epoll_event ev;
epoll_fd = epoll_create(512);
if (epoll_fd < 0) {
printf("epoll_create(): %s\n", strerror(errno));
exit(1);
}
listen_fd = socket(AF_INET, SOCK_STREAM, 0);
if (listen_fd < 0) {
printf("socket(): %s\n", strerror(errno));
exit(1);
}
nonblocking(listen_fd);
memset(&sock, 0, sizeof(struct sockaddr_in));
sock.sin_family = AF_INET;
sock.sin_port = htons(LISTEN_PORT);
inet_aton(LISTEN_HOST, &sock.sin_addr);
if (bind(listen_fd, (struct sockaddr *) &sock,
sizeof(struct sockaddr_in))
< 0)
{
printf("bind(): %s\n", strerror(errno));
exit(1);
}
if (listen(listen_fd, 512) < 0) {
printf("listen(): %s\n", strerror(errno));
exit(1);
}
memset(&ev, 0, sizeof(struct epoll_event));
ev.events = EPOLLIN|EPOLLOUT|EPOLLHUP|EPOLLERR|EPOLLRDHUP|EPOLLET;
ev.data.fd = listen_fd;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listen_fd, &ev) < 0) {
printf("epoll_ctl(): %s\n", strerror(errno));
exit(1);
}
epoll_loop(epoll_fd, listen_fd);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment