From 0457119acb36b89b6f2f4534fe8ad94b19540bbd Mon Sep 17 00:00:00 2001 From: Guangxiong Lin Date: Fri, 2 Dec 2022 12:18:57 +0800 Subject: Refactor --- Makefile | 6 +++- acceptor.c | 51 +++++++++++++++++++++++++++++++++ acceptor.h | 14 +++++++++ connection.c | 53 ++++++++++++++++++++++++++++++++++ connection.h | 15 ++++++++++ constant.h | 7 +++++ eventloop.c | 22 ++++++++++---- eventloop.h | 6 ++-- server.c | 93 ++++++------------------------------------------------------ tsocket.c | 3 +- util.c | 1 + util.h | 3 -- 12 files changed, 174 insertions(+), 100 deletions(-) create mode 100644 acceptor.c create mode 100644 acceptor.h create mode 100644 connection.c create mode 100644 connection.h create mode 100644 constant.h diff --git a/Makefile b/Makefile index 96eddce..333935f 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,9 @@ CC ?= gcc +.PHONY: debug +debug: CFLAGS += -g -DDEBUG=1 +debug: server client + .PHONY: all all: client server @@ -13,5 +17,5 @@ clean: client: client.o util.o $(CC) -o $@ $^ -server: server.o util.o eventloop.o tsocket.o +server: server.o util.o eventloop.o tsocket.o acceptor.o connection.o $(CC) -o $@ $^ diff --git a/acceptor.c b/acceptor.c new file mode 100644 index 0000000..bb4fb88 --- /dev/null +++ b/acceptor.c @@ -0,0 +1,51 @@ +#include +#include +#include + +#include "acceptor.h" +#include "util.h" +#include "connection.h" + +int connAcceptorAccept(struct connAcceptor *ca) +{ + struct tsocket *conn_sock = tsocketAccept(ca->sock); + if (conn_sock == NULL) { + perror("socket accept"); + return 0; + } + + if (setblocking(conn_sock->fd, false) == -1) { + perror("setblocking"); + tsocketDelete(conn_sock); + return 0; + } + + struct connection *conn = connectionNew(conn_sock); + struct event *conn_ev = connectionNewEvent(conn); + + if (eventLoopAdd(ca->el, conn_ev, EPOLLIN | EPOLLET) == -1) { + perror("eventloop add fd: conn_sock"); + return 0; + } + + printf("New client fd %d, ip: %s, port: %d\n", + conn_sock->fd, conn_sock->addr, conn_sock->port); + + return 0; +} + +void connAcceptorDel(struct connAcceptor *ca) +{ + tsocketDelete(ca->sock); + free(ca); +} + +struct event *connAcceptorNewEvent(struct tsocket *sock, struct eventLoop *el) +{ + struct connAcceptor *ca = malloc(sizeof(*ca)); + ca->sock = sock; + ca->el = el; + + struct event *ev = eventNew(ca, sock->fd, connAcceptorAccept, connectionDel); + return ev; +} diff --git a/acceptor.h b/acceptor.h new file mode 100644 index 0000000..8432ef6 --- /dev/null +++ b/acceptor.h @@ -0,0 +1,14 @@ +#include "tsocket.h" +#include "eventloop.h" + +#ifndef __ACCEPTOR_H +#define __ACCEPTOR_H + +struct connAcceptor { + struct tsocket *sock; + struct eventLoop *el; +}; + +struct event *connAcceptorNewEvent(struct tsocket *sock, struct eventLoop *el); + +#endif diff --git a/connection.c b/connection.c new file mode 100644 index 0000000..d12ab86 --- /dev/null +++ b/connection.c @@ -0,0 +1,53 @@ +#include +#include +#include +#include + +#include "connection.h" +#include "constant.h" + +#define READ_BUFFER_SIZE 1024 + +struct connection *connectionNew(struct tsocket *sock) +{ + struct connection *conn = malloc(sizeof(*conn)); + conn->sock = sock; + + return conn; +} + +void connectionDel(struct connection *conn) +{ + tsocketDelete(conn->sock); + free(conn); +} + +int echo(struct connection *conn) +{ + char buf[READ_BUFFER_SIZE]; + ssize_t n_read_bytes; + + struct tsocket *sock = (struct tsocket *)conn->sock; + + for (;;) { + n_read_bytes = read(sock->fd, buf, sizeof(buf)); + if (n_read_bytes > 0) { + printf("message from conn %d: %s\n", sock->fd, buf); + write(sock->fd, buf, sizeof(buf)); + } else if (n_read_bytes == 0) { + printf("conn %d disconnected\n", sock->fd); + return ERROR; + } else if (n_read_bytes == -1) { + if (errno == EAGAIN || errno == EWOULDBLOCK) + break; + } + } + + return OK; +} + +struct event *connectionNewEvent(struct connection *conn) +{ + return eventNew(conn, conn->sock->fd, echo, connectionDel); +} + diff --git a/connection.h b/connection.h new file mode 100644 index 0000000..c7b24fc --- /dev/null +++ b/connection.h @@ -0,0 +1,15 @@ +#include "tsocket.h" +#include "eventloop.h" + +#ifndef __CONNECTION_H +#define __CONNECTION_H + +struct connection { + struct tsocket *sock; +}; + +struct connection *connectionNew(struct tsocket *sock); +void connectionDel(struct connection *conn); +struct event *connectionNewEvent(struct connection *conn); + +#endif diff --git a/constant.h b/constant.h new file mode 100644 index 0000000..1bb6bf4 --- /dev/null +++ b/constant.h @@ -0,0 +1,7 @@ +#ifndef __CONSTANT_H +#define __CONSTANT_H + +#define ERROR -1 +#define OK 0 + +#endif diff --git a/eventloop.c b/eventloop.c index 970a521..ae4377c 100644 --- a/eventloop.c +++ b/eventloop.c @@ -3,6 +3,7 @@ #include "eventloop.h" #include "util.h" +#include "constant.h" struct eventLoop *eventLoopNew() { @@ -33,8 +34,6 @@ int eventLoopAdd(struct eventLoop *el, struct event *ev, int flag) epev.events = flag; epev.data.ptr = ev; - ev->el = el; - return epoll_ctl(el->epollfd, EPOLL_CTL_ADD, ev->fd, &epev); } @@ -55,7 +54,8 @@ void eventLoopLoop(struct eventLoop *el) for (int i = 0; i < nevents; i++) { ev = eventLoopGet(el, i); - ev->handle(ev); + if (ev->handle(ev->data) == -1) + eventLoopDel(el, ev); } } } @@ -66,9 +66,19 @@ int eventLoopDel(struct eventLoop *el, struct event *ev) return ERROR; if (ev->delete) - ev->delete(ev); - else - free(ev); + ev->delete(ev->data); + free(ev); return OK; } + +struct event *eventNew(void *data, int fd, void (*handle), void (*delete)) +{ + struct event *ev = malloc(sizeof(*ev)); + ev->data = data; + ev->handle = handle; + ev->fd = fd; + ev->delete = delete; + + return ev; +} diff --git a/eventloop.h b/eventloop.h index 490d515..9aafb68 100644 --- a/eventloop.h +++ b/eventloop.h @@ -15,10 +15,9 @@ struct eventLoop { struct event { int fd; - struct eventLoop *el; void *data; - void (*handle)(struct event *ev); - void (*delete)(struct event *ev); + int (*handle)(void *data); + void (*delete)(void *data); }; struct eventLoop *eventLoopNew(); @@ -27,5 +26,6 @@ int eventLoopAdd(struct eventLoop *el, struct event *ev, int flag); int eventLoopDel(struct eventLoop *el, struct event *ev); struct event *eventLoopGet(struct eventLoop *el, int index); void eventLoopLoop(struct eventLoop *el); +struct event *eventNew(void *data, int fd, void (*handle), void (*delete)); #endif diff --git a/server.c b/server.c index bab1edc..f4ad78d 100644 --- a/server.c +++ b/server.c @@ -13,88 +13,8 @@ #include "eventloop.h" #include "tsocket.h" #include "util.h" - -#define READ_BUFFER_SIZE 1024 - -void handleReadEvent(struct event *ev) -{ - char buf[READ_BUFFER_SIZE]; - ssize_t n_read_bytes; - - struct tsocket *sock = (struct tsocket *)ev->data; - - for (;;) { - n_read_bytes = read(sock->fd, buf, sizeof(buf)); - if (n_read_bytes > 0) { - printf("message from conn %d: %s\n", sock->fd, buf); - write(sock->fd, buf, sizeof(buf)); - } else if (n_read_bytes == 0) { - printf("conn %d disconnected\n", sock->fd); - eventLoopDel(ev->el, ev); - break; - } else if (n_read_bytes == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) - break; - } - } -} - -void serverDeleteReadEvent(struct event *ev) -{ - tsocketDelete(ev->data); - free(ev); -} - -struct event *serverNewReadEvent(struct tsocket *sock) -{ - struct event *ev = malloc(sizeof(*ev)); - ev->data = sock; - ev->handle = handleReadEvent; - ev->fd = sock->fd; - ev->delete = serverDeleteReadEvent; - - return ev; -} - -void handleNewClientConnection(struct event *ev) -{ - struct tsocket *conn_sock = tsocketAccept(ev->data); - if (conn_sock == NULL) { - perror("socket accept"); - return; - } - - if (setblocking(conn_sock->fd, false) == -1) { - perror("setblocking"); - tsocketDelete(conn_sock); - return; - } - - struct event *read_ev = serverNewReadEvent(conn_sock); - if (eventLoopAdd(ev->el, read_ev, EPOLLIN | EPOLLET) == -1) { - perror("eventloop add fd: conn_sock"); - return; - } - - printf("New client fd %d, ip: %s, port: %d\n", - conn_sock->fd, conn_sock->addr, conn_sock->port); -} - -struct event *serverNewAcceptEvent(const char *addr, int port) -{ - struct tsocket *sock = tsocketNew(); - if (sock == NULL - || tsocketBind(sock, addr, port) == -1 - || tsocketListen(sock) == -1) - return NULL; - - struct event *ev = malloc(sizeof(*ev)); - ev->handle = handleNewClientConnection; - ev->data = sock; - ev->fd = sock->fd; - - return ev; -} +#include "connection.h" +#include "acceptor.h" int main() { @@ -102,10 +22,13 @@ int main() if (el == NULL) panic("eventloop creation"); - struct event *acceptEvent = serverNewAcceptEvent("127.0.0.1", 8888); - if (acceptEvent == NULL) - panic("server client connection event"); + struct tsocket *sock = tsocketNew(); + if (sock == NULL + || tsocketBind(sock, "127.0.0.1", 8888) == -1 + || tsocketListen(sock) == -1) + panic("socket creation"); + struct event *acceptEvent = connAcceptorNewEvent(sock, el); if (eventLoopAdd(el, acceptEvent, EPOLLIN) == -1) panic("eventloop add fd"); diff --git a/tsocket.c b/tsocket.c index d1d0368..76e6064 100644 --- a/tsocket.c +++ b/tsocket.c @@ -5,8 +5,7 @@ #include "tsocket.h" -struct tsocket * -tsocketNew() +struct tsocket *tsocketNew() { int fd = socket(AF_INET, SOCK_STREAM, 0); if (fd == -1) diff --git a/util.c b/util.c index a44cc66..b4053fd 100644 --- a/util.c +++ b/util.c @@ -5,6 +5,7 @@ #include #include "util.h" +#include "constant.h" void panic(const char *msg) { diff --git a/util.h b/util.h index c0f0214..850a245 100644 --- a/util.h +++ b/util.h @@ -3,9 +3,6 @@ #ifndef __UTIL_H #define __UTIL_H -#define ERROR -1 -#define OK 0 - void panic(const char *); int setblocking(int fd, bool blocking); -- cgit v1.2.3