#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/epoll.h>
#include <string.h>
#include <stdlib.h>
#define BUFFER_LENGTH 128
#define EVENTS_LENGTH 128
struct sock_item {
int fd;
char *rbuffer;
int rlength;
char *wbuffer;
int wlength;
int event;
void (*recv_cb)(int fd, char *buffer, int length);
void (*send_cb)(int fd, char *buffer, int length);
void (*accept_cb)(int fd, char *buffer, int length);
};
struct reactor {
int epfd;
struct sock_item *items;
};
void *routine(void *arg) {
int clientfd = *(int *)arg;
while (1) {
unsigned char buffer[BUFFER_LENGTH] = {0};
int ret = recv(clientfd, buffer, BUFFER_LENGTH, 0);
if (ret == 0) {
close(clientfd);
break;
}
printf("buffer : %s, ret: %d\n", buffer, ret);
ret = send(clientfd, buffer, ret, 0);
}
}
int main() {
int listenfd = socket(AF_INET, SOCK_STREAM, 0);
if (listenfd == -1) return -1;
struct sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(9999);
if (-1 == bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) {
return -2;
}
#if 0
int flag = fcntl(listenfd, F_GETFL, 0);
flag |= O_NONBLOCK;
fcntl(listenfd, F_SETFL, flag);
#endif
listen(listenfd, 10);
struct reactor *r = (struct reactor*)calloc(1, sizeof(struct reactor));
if (r == NULL) {
return -3;
}
r->items = (struct sock_item*)calloc(EVENTS_LENGTH, sizeof(struct sock_item));
if (r->items == NULL) return -4;
r->epfd = epoll_create(1);
struct epoll_event ev, events[EVENTS_LENGTH];
ev.events = EPOLLIN;
ev.data.fd = listenfd;
epoll_ctl(r->epfd, EPOLL_CTL_ADD, listenfd, &ev);
while (1) {
int nready = epoll_wait(r->epfd, events, EVENTS_LENGTH, -1);
printf("------- %d\n", nready);
int i = 0;
for (i = 0;i < nready;i ++) {
int clientfd= events[i].data.fd;
if (listenfd == clientfd) {
struct sockaddr_in client;
socklen_t len = sizeof(client);
int connfd = accept(listenfd, (struct sockaddr*)&client, &len);
if (connfd == -1) break;
printf("accept: %d\n", connfd);
ev.events = EPOLLIN;
ev.data.fd = connfd;
epoll_ctl(r->epfd, EPOLL_CTL_ADD, connfd, &ev);
r->items[connfd].rbuffer = calloc(1, BUFFER_LENGTH);
r->items[connfd].rlength = 0;
r->items[connfd].wbuffer = calloc(1, BUFFER_LENGTH);
r->items[connfd].wlength = 0;
r->items[connfd].event = EPOLLIN;
} else if (events[i].events & EPOLLIN) {
char *rbuffer = r->items[clientfd].rbuffer;
char *wbuffer = r->items[clientfd].wbuffer;
int n = recv(clientfd, rbuffer, BUFFER_LENGTH, 0);
if (n > 0) {
printf("recv: %s, n: %d\n", rbuffer, n);
memcpy(wbuffer, rbuffer, BUFFER_LENGTH);
ev.events = EPOLLOUT;
ev.data.fd = clientfd;
epoll_ctl(r->epfd, EPOLL_CTL_MOD, clientfd, &ev);
}
} else if (events[i].events & EPOLLOUT) {
char *wbuffer = r->items[clientfd].wbuffer;
int sent = send(clientfd, wbuffer, BUFFER_LENGTH, 0);
printf("sent: %d\n", sent);
ev.events = EPOLLIN;
ev.data.fd = clientfd;
epoll_ctl(r->epfd, EPOLL_CTL_MOD, clientfd, &ev);
}
}
}
}