aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--acceptor.c51
-rw-r--r--acceptor.h14
-rw-r--r--connection.c53
-rw-r--r--connection.h15
-rw-r--r--constant.h7
-rw-r--r--eventloop.c22
-rw-r--r--eventloop.h6
-rw-r--r--server.c93
-rw-r--r--tsocket.c3
-rw-r--r--util.c1
-rw-r--r--util.h3
12 files changed, 174 insertions, 100 deletions
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 <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#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 <stdlib.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#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 <sys/types.h>
#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);