#include #include #include #include #include #include #include #include #include #include "chat.h" typedef struct __wclient_args_t { sockaddr_in new_addr; socklen_t new_addr_siz; int aux; int *bread; int *sock; std::string log; int *lpos; } wclient_args_t; typedef struct __wserver_args_t { sockaddr_in new_addr; socklen_t new_addr_siz; int aux; int *bread; int *lpos; std::string log; } wserver_args_t; /* * client_start(listen_ip, listen_port, &socket_descriptor_client, log_path, &client_wait_thread); */ void client_start(std::string ip, int port, int *sock, std::string log, pthread_t *thr) { char msg[1024]; int bread; int bwrit; sockaddr_in send_addr; struct timeval time_start; struct timeval time_end; struct hostent *host = gethostbyname(ip.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(port); *sock = socket(AF_INET, SOCK_STREAM, 0); attempt_client_connection: int stat = connect(*sock, (sockaddr *)&send_addr, sizeof(send_addr)); if (stat < 0) { log_append(log, "Error connecting to socket, retrying..."); goto attempt_client_connection; } log_append(log, "Connected to the server!"); bread = bwrit = 0; gettimeofday(&time_start, NULL); a->aux = *sock; pthread_create(thr, nullptr, poll_server, a); pthread_detach(*thr); } int server_start(int port, int *sock, std::string log, pthread_t *thr, struct timeval *ts) { 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 */ *sock = socket(AF_INET, SOCK_STREAM, 0); if (*sock < 0) return 1; /* bind sock to its local addr */ bstat = bind(*sock, (struct sockaddr *)&srv_addr, sizeof(srv_addr)); if (bstat < 0) return 1; log_append(log, "Waiting for a client to connect..."); /* listen for up to 5 simultaneous requests */ listen(*sock, 5); a->new_addr = newsock; a->new_addr_siz = newsock_siz; rc = pthread_create(thr, nullptr, await_client, a); pthread_detach(*thr); log_append(log, "Server started successfully."); gettimeofday(ts, NULL); return 0; } void * await_client(void *args) { wclient_args_t *a = static_cast(a); *a->sock = accept(*a->sock, (sockaddr *)&a->new_addr, &a->new_addr_siz); if (*a->sock >= 0) { log_append(a->log, "client connected"); if (count_lines(a->log) > LOG_LENGTH) ++*a->lpos; file_disp(a->log, *a->lpos, LOG_LENGTH); } /* get what we need for the return and throw the rest away */ int *s = a->sock; int *b = a->bread; std::string l = a->log; int *p = a->lpos; delete a; return poll_client(s, b, l, p); } void * poll_client(int *sock, int *bread, std::string log, int *lpos) { char msg[1024]; for (;;) { /* listen for msg from client */ memset(&msg, 0, sizeof(msg)); /* clear buf */ *bread += recv(*sock, (char *)&msg, sizeof(msg), 0); log_append(log, msg); if (count_lines(log) > LOG_LENGTH) ++*lpos; file_disp(log, *lpos, LOG_LENGTH); } return nullptr; } void * poll_server(void *args) { wserver_args_t *a = static_cast(args); int sock_desc = (int)a->aux; char msg[1024]; for (;;) { memset(&msg, 0, sizeof(msg)); *a->bread += recv(sock_desc, (char *)&msg, sizeof(msg), 0); log_append(a->log, msg); if (count_lines(a->log) > LOG_LENGTH) ++*a->lpos; file_disp(a->log, *a->lpos, LOG_LENGTH); } delete a; } void server_stop(struct timeval *start, struct timeval *end, int *sock, int *bread, int *bwrit) { long e = end->tv_sec - start->tv_sec; gettimeofday(end, NULL); close(*sock); /* Don't just die silently */ puts("********Session********"); printf("Bytes written: %i\nBytes Read: %i\n", *bwrit, *bread); printf("Elapsed time: %ld\n secs\n", e); puts("Connection closed..."); } void client_stop(struct timeval *start, struct timeval *end, int *sock, int *bread, int *bwrit) { long e = end->tv_sec - start->tv_sec; gettimeofday(end, NULL); close(*sock); puts("********Session********"); printf("Bytes written: %i\nBytes read: %i\n", *bwrit, *bread); printf("Elapsed time: %ld\n secs\n", e); puts("Connection closed..."); }