From e339f2d269fcaffed7beed67c3995fe3b67393eb Mon Sep 17 00:00:00 2001 From: Guangxiong Lin Date: Sat, 17 Dec 2022 21:24:04 +0800 Subject: Support on_connect function in server lib --- Makefile | 3 ++- example/Makefile | 21 +++++++++++++++++++++ example/client.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ example/server.c | 36 ++++++++++++++++++++++++++++++++++++ src/Makefile | 13 ++++--------- src/acceptor.c | 16 +++++++++++----- src/acceptor.h | 7 ++++++- src/client.c | 48 ------------------------------------------------ src/connection.c | 35 ++++++----------------------------- src/connection.h | 6 +++++- src/evloop.c | 2 +- src/server.c | 16 ++++++++++------ src/server.h | 5 +++++ src/tsocket.c | 5 +++++ src/tsocket.h | 2 ++ 15 files changed, 161 insertions(+), 101 deletions(-) create mode 100644 example/Makefile create mode 100644 example/client.c create mode 100644 example/server.c delete mode 100644 src/client.c diff --git a/Makefile b/Makefile index 1c79ae9..b49b574 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,5 @@ default: all .DEFAULT: - cd src && $(MAKE) $@ + cd src && $(MAKE) $@ \ + && cd ../example && $(MAKE) $@ diff --git a/example/Makefile b/example/Makefile new file mode 100644 index 0000000..6f0fff8 --- /dev/null +++ b/example/Makefile @@ -0,0 +1,21 @@ +SERVER_NAME=server +SERVER_OBJ=server.o ../src/server.o ../src/tsocket.o ../src/util.o ../src/evloop.o ../src/tpool.o ../src/connection.o ../src/acceptor.o + +CLIENT_NAME=client +CLIENT_OBJ=client.o ../src/util.o + +.PHONY: all +all: $(SERVER_NAME) $(CLIENT_NAME) + +%.o: %.c + $(CC) -c $(CFLAGS) $< -o $@ + +$(SERVER_NAME): $(SERVER_OBJ) + $(CC) -o $@ $^ + +$(CLIENT_NAME): $(CLIENT_OBJ) + $(CC) -o $@ $^ + +.PHONY: clean +clean: + rm -rf $(CLIENT_NAME) $(SERVER_NAME) *.o diff --git a/example/client.c b/example/client.c new file mode 100644 index 0000000..56ba072 --- /dev/null +++ b/example/client.c @@ -0,0 +1,47 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "../src/util.h" + +int main() +{ + int sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd == -1) + panic("socket creation error"); + + struct sockaddr_in serv_addr; + bzero(&serv_addr, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + serv_addr.sin_port = htons(8888); + + if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1) + panic("socket connect error"); + + for (;;) { + char buf[1024]; + bzero(&buf, sizeof(buf)); + scanf("%s", buf); + ssize_t n_write_bytes = write(sockfd, buf, sizeof(buf)); + if (n_write_bytes == -1) { + printf("socket already disconnected, cannot write any more!\n"); + break; + } + + ssize_t n_read_bytes = read(sockfd, buf, sizeof(buf)); + if (n_read_bytes > 0) { + printf("message from server: %s\n", buf); + } else if (n_read_bytes == 0) { + printf("server socket disconnected!\n"); + break; + } else if (n_read_bytes == -1) { + close(sockfd); + panic("socket read error"); + } + } +} diff --git a/example/server.c b/example/server.c new file mode 100644 index 0000000..fe8cba9 --- /dev/null +++ b/example/server.c @@ -0,0 +1,36 @@ +#include +#include +#include + +#include "../src/server.h" +#include "../src/connection.h" + +#define READ_BUFFER_SIZE 1024 + +static void echo(connection_t *conn) +{ + char buf[READ_BUFFER_SIZE]; + ssize_t n_read_bytes; + int fd = connection_fd(conn); + + for (;;) { + n_read_bytes = read(fd, buf, sizeof(buf)); + if (n_read_bytes > 0) { + printf("message from conn %d: %s\n", fd, buf); + write(fd, buf, sizeof(buf)); + } else if (n_read_bytes == 0) { + printf("conn %d disconnected\n", fd); + return; + } else if (n_read_bytes == -1) { + if (errno == EAGAIN || errno == EWOULDBLOCK) + break; + } + } +} + +int main() +{ + server_t *serv = server_create(); + server_on_connect(serv, echo); + server_run(serv); +} diff --git a/src/Makefile b/src/Makefile index bceb62e..a478ecf 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,22 +1,17 @@ CC ?= gcc CFLAGS ?= -lpthread +SOURCES := $(wildcard *.c) +OBJECTS := $(patsubst %.c, %.o, $(SOURCES)) .PHONY: all -all: client server +all: $(OBJECTS) .PHONY: debug debug: CFLAGS += -g -DDEBUG=1 -debug: server client .PHONY: clean clean: - rm -rf client server *.o + rm -rf *.o %.o: %.c $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@ - -client: client.o util.o - $(CC) -o $@ $^ - -server: server.o util.o evloop.o tsocket.o acceptor.o connection.o tpool.o - $(CC) -o $@ $^ diff --git a/src/acceptor.c b/src/acceptor.c index ca7bfb4..2d883d1 100644 --- a/src/acceptor.c +++ b/src/acceptor.c @@ -13,6 +13,7 @@ struct conn_acceptor { tsocket_t *sock; evloop_t **evloops; int nevloops; + connection_callback_func_t conn_callback_func; }; conn_acceptor_t *conn_acceptor_create(tsocket_t *sock, evloop_t **evloops, int nevloops) @@ -24,6 +25,7 @@ conn_acceptor_t *conn_acceptor_create(tsocket_t *sock, evloop_t **evloops, int n acceptor->sock = sock; acceptor->evloops = evloops; acceptor->nevloops = nevloops; + acceptor->conn_callback_func = NULL; return acceptor; } @@ -42,7 +44,7 @@ static void conn_acceptor_accept(conn_acceptor_t *ca) return; } - event_t *conn_ev = connection_create_event(conn_sock); + event_t *conn_ev = connection_event_create(conn_sock, ca->conn_callback_func); // TODO: Use a better way to decide which sub reactor to use. int ind = conn_sock->fd % ca->nevloops; @@ -55,18 +57,22 @@ static void conn_acceptor_accept(conn_acceptor_t *ca) conn_sock->fd, conn_sock->addr, conn_sock->port); } -static void conn_acceptor_destroy(conn_acceptor_t *ca) +void conn_acceptor_destroy(conn_acceptor_t *ca) { tsocket_destroy(ca->sock); free(ca); } -event_t *conn_acceptor_event_create(struct tsocket *sock, evloop_t **evloops, int nevloops) +event_t *conn_acceptor_event_create(conn_acceptor_t *acceptor) { - conn_acceptor_t *acceptor = conn_acceptor_create(sock, evloops, nevloops); - event_t *ev = event_create(acceptor, sock->fd, + event_t *ev = event_create(acceptor, acceptor->sock->fd, (evloop_process_func_t) conn_acceptor_accept, (evloop_destroy_func_t) conn_acceptor_destroy); return ev; } + +void conn_acceptor_on_connect(conn_acceptor_t *acceptor, connection_callback_func_t func) +{ + acceptor->conn_callback_func = func; +} diff --git a/src/acceptor.h b/src/acceptor.h index 2d16a13..4c208b6 100644 --- a/src/acceptor.h +++ b/src/acceptor.h @@ -1,5 +1,6 @@ #include "tsocket.h" #include "evloop.h" +#include "connection.h" #ifndef __ACCEPTOR_H #define __ACCEPTOR_H @@ -7,6 +8,10 @@ struct conn_acceptor; typedef struct conn_acceptor conn_acceptor_t; -event_t *conn_acceptor_event_create(struct tsocket *sock, evloop_t **evloops, int nevloops); +conn_acceptor_t *conn_acceptor_create(tsocket_t *sock, evloop_t **evloops, int nevloops); +void conn_acceptor_destroy(conn_acceptor_t *acceptor); +event_t *conn_acceptor_event_create(conn_acceptor_t *ca); + +void conn_acceptor_on_connect(conn_acceptor_t *acceptor, connection_callback_func_t func); #endif diff --git a/src/client.c b/src/client.c deleted file mode 100644 index 0b9cbfe..0000000 --- a/src/client.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "util.h" - -int -main() -{ - int sockfd = socket(AF_INET, SOCK_STREAM, 0); - if (sockfd == -1) - panic("socket creation error"); - - struct sockaddr_in serv_addr; - bzero(&serv_addr, sizeof(serv_addr)); - serv_addr.sin_family = AF_INET; - serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); - serv_addr.sin_port = htons(8888); - - if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1) - panic("socket connect error"); - - for (;;) { - char buf[1024]; - bzero(&buf, sizeof(buf)); - scanf("%s", buf); - ssize_t n_write_bytes = write(sockfd, buf, sizeof(buf)); - if (n_write_bytes == -1) { - printf("socket already disconnected, cannot write any more!\n"); - break; - } - - ssize_t n_read_bytes = read(sockfd, buf, sizeof(buf)); - if (n_read_bytes > 0) { - printf("message from server: %s\n", buf); - } else if (n_read_bytes == 0) { - printf("server socket disconnected!\n"); - break; - } else if (n_read_bytes == -1) { - close(sockfd); - panic("socket read error"); - } - } -} diff --git a/src/connection.c b/src/connection.c index c164ec8..ce71b3a 100644 --- a/src/connection.c +++ b/src/connection.c @@ -1,13 +1,8 @@ #include -#include -#include -#include #include "connection.h" #include "constant.h" -#define READ_BUFFER_SIZE 1024 - struct connection { struct tsocket *sock; }; @@ -26,33 +21,15 @@ void connection_destroy(struct connection *conn) free(conn); } -static void 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; - } else if (n_read_bytes == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) - break; - } - } -} - -event_t *connection_create_event(struct tsocket *sock) +event_t *connection_event_create(struct tsocket *sock, connection_callback_func_t func) { connection_t *conn = connection_create(sock); return event_create(conn, conn->sock->fd, - (evloop_process_func_t) echo, + (evloop_process_func_t) func, (evloop_destroy_func_t) connection_destroy); } +int connection_fd(connection_t *conn) +{ + return tsocket_fd(conn->sock); +} diff --git a/src/connection.h b/src/connection.h index 4e14487..ce39a7c 100644 --- a/src/connection.h +++ b/src/connection.h @@ -7,9 +7,13 @@ struct connection; typedef struct connection connection_t; +typedef void (*connection_callback_func_t)(connection_t *conn); + connection_t *connection_create(struct tsocket *sock); void connection_destroy(struct connection *conn); -event_t *connection_create_event(struct tsocket *sock); +event_t *connection_event_create(struct tsocket *sock, connection_callback_func_t func); + +int connection_fd(connection_t *conn); #endif diff --git a/src/evloop.c b/src/evloop.c index 5002b24..b9886bd 100644 --- a/src/evloop.c +++ b/src/evloop.c @@ -63,7 +63,7 @@ void evloop_loop(evloop_t *el) for (int i = 0; i < nevents; i++) { ev = evloop_get(el, i); - if (ev->process(ev->data) == -1) + if (ev->process && ev->process(ev->data) == -1) evloop_remove(el, ev); } } diff --git a/src/server.c b/src/server.c index a13d525..e4a2182 100644 --- a/src/server.c +++ b/src/server.c @@ -22,6 +22,7 @@ struct server { tpool_t *tpool; evloop_t *evloop; evloop_t **subevloops; + conn_acceptor_t *acceptor; }; server_t *server_create(void) @@ -29,6 +30,7 @@ server_t *server_create(void) int nprocs = get_nprocs(); server_t *serv = (server_t *)malloc(sizeof(*serv)); tsocket_t *sock; + conn_acceptor_t *acceptor; event_t *acceptor_event; if (!(sock = tsocket_create()) @@ -46,7 +48,9 @@ server_t *server_create(void) for (int i = 0; i < nprocs; i++) serv->subevloops[i] = evloop_create(); - if (!(acceptor_event = conn_acceptor_event_create(sock, serv->subevloops, nprocs))) + serv->acceptor = conn_acceptor_create(sock, serv->subevloops, nprocs); + + if (!(acceptor_event = conn_acceptor_event_create(serv->acceptor))) return NULL; if (evloop_add(serv->evloop, acceptor_event, EPOLLIN) == -1) panic("evloop add fd"); @@ -67,6 +71,7 @@ void server_destroy(server_t *serv) evloop_destroy(serv->evloop); tpool_destroy(serv->tpool); + conn_acceptor_destroy(serv->acceptor); for (int i = 0; i < nprocs; i++) evloop_destroy(serv->subevloops[i]); @@ -75,13 +80,12 @@ void server_destroy(server_t *serv) free(serv); } -void server_run(server_t *serv) +void server_on_connect(server_t *serv, connection_callback_func_t func) { - evloop_loop(serv->evloop); + conn_acceptor_on_connect(serv->acceptor, func); } -int main() +void server_run(server_t *serv) { - server_t *serv = server_create(); - server_run(serv); + evloop_loop(serv->evloop); } diff --git a/src/server.h b/src/server.h index 44c5434..df53c2a 100644 --- a/src/server.h +++ b/src/server.h @@ -1,3 +1,5 @@ +#include "connection.h" + #ifndef __SERVER_H #define __SERVER_H @@ -5,6 +7,9 @@ struct server; typedef struct server server_t; server_t *server_create(void); +void server_destroy(server_t *serv); + +void server_on_connect(server_t *serv, connection_callback_func_t func); void server_run(server_t *serv); diff --git a/src/tsocket.c b/src/tsocket.c index 8d8038a..9e55950 100644 --- a/src/tsocket.c +++ b/src/tsocket.c @@ -57,3 +57,8 @@ void tsocket_destroy(struct tsocket *sock) close(sock->fd); free(sock); } + +int tsocket_fd(tsocket_t *sock) +{ + return sock->fd; +} diff --git a/src/tsocket.h b/src/tsocket.h index 5028b04..4e782ca 100644 --- a/src/tsocket.h +++ b/src/tsocket.h @@ -16,4 +16,6 @@ int tsocket_listen(struct tsocket *sock); struct tsocket *tsocket_accept(struct tsocket *sock); void tsocket_destroy(struct tsocket *sock); +int tsocket_fd(tsocket_t *sock); + #endif -- cgit v1.2.3