diff --git a/src/Makefile b/src/Makefile index 0c83d1e..781b146 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,7 +2,7 @@ CXX = g++ CXXFLAGS = -pthread -Wall -Wextra -O2 -std=c++17 LDFLAGS = -lcurses TARGET = ct -CXX_SRCS = main.cc +CXX_SRCS = main.cc net.cc CXX_OBJS = $(CXX_SRCS:.cc=.o) all: $(TARGET) diff --git a/src/chat.h b/src/chat.h index 2b53d1a..4d1decf 100644 --- a/src/chat.h +++ b/src/chat.h @@ -3,17 +3,25 @@ #include +#include +#include + +#define LOG_LENGTH 10 + +typedef struct __wclient_args_t wclient_args_t; + void *await_client(void *a); void clear_rows(int s, int e); int count_lines(std::string p); int file_disp(std::string p, int lnstart, int lncount = 10); int log_append(std::string p, std::string ln); int log_linect(std::string p); -void client_start(void); -void client_stop(void); -void *poll_client(void); -void *poll_server(void *a); -void server_start(int port); -void server_stop(void); +void client_start(std::string ip, int port, int *sock, std::string log, pthread_t *thr); +void client_stop(struct timeval *start, struct timeval *end, int *sock, int *bread, int *bwrit); +void *poll_client(int *sock, int *bread, std::string log, int *lpos); +void *poll_server(void *args); +int +server_start(int port, int *sock, std::string log, pthread_t *thr, struct timeval *ts); +void server_stop(struct timeval *start, struct timeval *end, int *sock, int *bread, int *bwrit); #endif diff --git a/src/main.cc b/src/main.cc index 8e1f16d..e76e766 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,5 +1,4 @@ #include -#include #include #include #include @@ -22,15 +21,9 @@ typedef enum { NO_MODE = 0, SERVER_MODE = 1, CLIENT_MODE = 2 } chatmode_t; -typedef struct { - sockaddr_in new_addr; - socklen_t new_addr_siz; - int aux; -} wclient_args_t; - chatmode_t mode = NO_MODE; -const int LOG_LENGTH = 10; +// const int LOG_LENGTH = 10; int line_position = 0; const int CURSOR_DEFAULT_POSITION_X = 2; @@ -54,6 +47,7 @@ pthread_t client_wait_thread; int main(int argc, char *argv[]) { + int err = 0; char *usr_in = new char[1024]; bool quit = false; @@ -70,11 +64,13 @@ main(int argc, char *argv[]) switch (mode) { case CLIENT_MODE: log_append(log_path, "CLIENT MODE"); - client_start(); + client_start(listen_ip_address, listen_port, &socket_descriptor_client, log_path, &client_wait_thread); break; case SERVER_MODE: log_append(log_path, "SERVER MODE"); - server_start(listen_port); + err = server_start(listen_port, &socket_descriptor_server, log_path, &client_wait_thread, &time_start); + if (err) + goto panic_no_server_sock; break; default: goto panic_no_mode; @@ -103,10 +99,10 @@ main(int argc, char *argv[]) switch (mode) { case CLIENT_MODE: - client_stop(); + client_stop(&time_start, &time_end, &socket_descriptor_client, &bytes_read, &bytes_written); break; case SERVER_MODE: - server_stop(); + server_stop(&time_start, &time_end, &socket_descriptor_server, &bytes_read, &bytes_written); break; default: goto panic_no_mode; @@ -127,6 +123,11 @@ panic_no_mode: fprintf(stderr, "Fatal: Mode was set to invalid enum %i\n", mode); return 1; + +panic_no_server_sock: + endwin(); + fprintf(stderr, "Fatal: Could not establish server socket!\n"); + return 1; } void @@ -189,181 +190,6 @@ count_lines(std::string p) return c; } -void * -await_client(void *a) -{ - wclient_args_t *args = static_cast(a); - - socket_descriptor_client = accept(socket_descriptor_server, (sockaddr *)&args->new_addr, &args->new_addr_siz); - - if (socket_descriptor_client >= 0) { - log_append(log_path, "client connected"); - - if (count_lines(log_path) > LOG_LENGTH) - line_position++; - - file_disp(log_path, line_position, LOG_LENGTH); - } - - delete args; - - return poll_client(); -} - -void * -poll_client(void) -{ - char msg[1024]; - for (;;) { - /* listen for msg from client */ - memset(&msg, 0, sizeof(msg)); /* clear buf */ - bytes_read += recv(socket_descriptor_client, (char *)&msg, sizeof(msg), 0); - log_append(log_path, msg); - - if (count_lines(log_path) > LOG_LENGTH) - line_position++; - - file_disp(log_path, line_position, LOG_LENGTH); - } - - return nullptr; -} - -void -server_start(int port) -{ - auto *a = new wclient_args_t{}; - sockaddr_in srv_addr; - sockaddr_in newsock; - socklen_t newsock_siz = sizeof(newsock); - int bstat; - int rc; - - /* set up socket and connection tools */ - bzero((char *)&srv_addr, sizeof(srv_addr)); - srv_addr.sin_family = AF_INET; - srv_addr.sin_addr.s_addr = htonl(INADDR_ANY); - srv_addr.sin_port = htons(port); - - /* open stream-oriented socket w inet addr and track sock descriptor */ - socket_descriptor_server = socket(AF_INET, SOCK_STREAM, 0); - if (socket_descriptor_server < 0) - goto panic_if_no_server_sock; - - /* bind sock to its local addr */ - bstat = bind(socket_descriptor_server, (struct sockaddr *)&srv_addr, sizeof(srv_addr)); - if (bstat < 0) - goto panic_if_no_server_sock; - - log_append(log_path, "Waiting for a client to connect..."); - - /* listen for up to 5 simultaneous requests */ - listen(socket_descriptor_server, 5); - a->new_addr = newsock; - a->new_addr_siz = newsock_siz; - - rc = pthread_create(&client_wait_thread, nullptr, await_client, a); - - pthread_detach(client_wait_thread); - - log_append(log_path, "Server started successfully."); - - gettimeofday(&time_start, NULL); - - return; - -panic_if_no_server_sock: - endwin(); - fprintf(stderr, "Fatal: Could not establish server socket!\n"); - exit(1); -} - -void -server_stop(void) -{ - long e = time_end.tv_sec - time_start.tv_sec; - - gettimeofday(&time_end, NULL); - close(socket_descriptor_server); - - /* Don't just die silently */ - puts("********Session********"); - printf("Bytes written: %i\nBytes Read: %i\n", bytes_written, bytes_read); - printf("Elapsed time: %ld\n secs\n", e); - puts("Connection closed..."); -} - -void -client_stop(void) -{ - long e = time_end.tv_sec - time_start.tv_sec; - - gettimeofday(&time_end, NULL); - close(socket_descriptor_client); - puts("********Session********"); - printf("Bytes written: %i\nBytes read: %i\n", bytes_written, bytes_read); - printf("Elapsed time: %ld\n secs\n", e); - puts("Connection closed..."); -} - -void * -poll_server(void *args) -{ - wclient_args_t *a = static_cast(args); - int sock_desc = (int)a->aux; - char msg[1024]; - - for (;;) { - memset(&msg, 0, sizeof(msg)); - bytes_read += recv(sock_desc, (char *)&msg, sizeof(msg), 0); - - log_append(log_path, msg); - - if (count_lines(log_path) > LOG_LENGTH) - line_position++; - - file_disp(log_path, line_position, LOG_LENGTH); - } -} - -void -client_start(void) -{ - char msg[1024]; - int bread; - int bwrit; - int rc; - sockaddr_in send_addr; - - struct timeval time_start; - struct timeval time_end; - struct hostent *host = gethostbyname(listen_ip_address.c_str()); - - auto *a = new wclient_args_t{}; - - bzero((char *)&send_addr, sizeof(send_addr)); - send_addr.sin_family = AF_INET; - send_addr.sin_addr.s_addr = inet_addr(inet_ntoa(*(struct in_addr *)*host->h_addr_list)); - send_addr.sin_port = htons(listen_port); - socket_descriptor_client = socket(AF_INET, SOCK_STREAM, 0); - -attempt_client_connection: - int stat = connect(socket_descriptor_client, (sockaddr *)&send_addr, sizeof(send_addr)); - if (stat < 0) { - log_append(log_path, "Error connecting to socket, retrying..."); - goto attempt_client_connection; - } - - log_append(log_path, "Connected to the server!"); - bread = bwrit = 0; - - gettimeofday(&time_start, NULL); - - a->aux = socket_descriptor_client; - rc = pthread_create(&client_wait_thread, nullptr, poll_server, a); - pthread_detach(client_wait_thread); -} - int log_append(std::string p, std::string ln) {