diff --git a/Makefile.am b/Makefile.am index 06a6612..9952823 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,2 +1,2 @@ bin_PROGRAMS = server -server_SOURCES = src/server/server.c src/server/clients.h src/server/clients.c +server_SOURCES = src/server/server.c src/server/xmppclient.h src/server/xmppclient.c diff --git a/src/server/clients.c b/src/server/clients.c deleted file mode 100644 index 27a44d1..0000000 --- a/src/server/clients.c +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "server/clients.h" - -GSList *clients; - -pthread_mutex_t clients_lock; -pthread_mutexattr_t lock_attr; - -void -clients_init(void) -{ - // initialise recursive mutex - pthread_mutexattr_init(&lock_attr); - pthread_mutexattr_settype(&lock_attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&clients_lock, &lock_attr); -} - -ChatClient* -clients_new(struct sockaddr_in client_addr, int socket) -{ - ChatClient *client = malloc(sizeof(ChatClient)); - client->ip = strdup(inet_ntoa(client_addr.sin_addr)); - client->port = ntohs(client_addr.sin_port); - client->sock = socket; - client->nickname = NULL; - - return client; -} - -void -clients_add(ChatClient *client) -{ - pthread_mutex_lock(&clients_lock); - clients = g_slist_append(clients, client); - pthread_mutex_unlock(&clients_lock); -} - -void -clients_print_total(void) -{ - pthread_mutex_lock(&clients_lock); - printf("Connected clients: %d\n", g_slist_length(clients)); - pthread_mutex_unlock(&clients_lock); -} diff --git a/src/server/clients.h b/src/server/clients.h deleted file mode 100644 index 137d556..0000000 --- a/src/server/clients.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef __H_CLIENTS -#define __H_CLIENTS - -#include - -typedef struct thread_client_t { - char *ip; - int port; - int sock; - char *nickname; -} ChatClient; - -void clients_init(void); - -ChatClient* clients_new(struct sockaddr_in client_addr, int socket); -void clients_add(ChatClient *client); - -void clients_print_total(void); -void clients_register(ChatClient *client, char *nickname); -void clients_broadcast_message(char *from, char *message); -void clients_end_session(ChatClient *client); - -#endif \ No newline at end of file diff --git a/src/server/server.c b/src/server/server.c index 418eca3..d9b0b0e 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -5,17 +5,17 @@ #include #include -#include "server/clients.h" +#include "server/xmppclient.h" #define STREAM_REQ "" #define STREAM_RESP "" #define FEATURES "" #define AUTH_REQ "stabberpasswordprofanity" #define AUTH_RESP "" +#define END_STREAM "" -void* connection_handler(void *data) +void connection_handler(XMPPClient *client) { - ChatClient *client = (ChatClient *)data; int read_size; // client loop @@ -38,12 +38,14 @@ void* connection_handler(void *data) // error if (read_size == -1) { perror("Error receiving on connection"); + xmppclient_end_session(client); g_string_free(stream, TRUE); break; // client closed } else if (read_size == 0) { - printf("%s:%d - Client disconnected.\n", client->ip, client->port); + printf("\n%s:%d - Client disconnected.\n", client->ip, client->port); + xmppclient_end_session(client); g_string_free(stream, TRUE); break; @@ -80,7 +82,7 @@ void* connection_handler(void *data) memset(buf, 0, sizeof(buf)); - // listen to client stream + // wait for auth request stream = g_string_new(""); errno = 0; gboolean received = FALSE; @@ -95,12 +97,14 @@ void* connection_handler(void *data) // error if (read_size == -1) { perror("Error receiving on connection"); + xmppclient_end_session(client); g_string_free(stream, TRUE); break; // client closed } else if (read_size == 0) { - printf("%s:%d - Client disconnected.\n", client->ip, client->port); + printf("\n%s:%d - Client disconnected.\n", client->ip, client->port); + xmppclient_end_session(client); g_string_free(stream, TRUE); break; @@ -122,11 +126,43 @@ void* connection_handler(void *data) fflush(stdout); memset(buf, 0, sizeof(buf)); + + // wait until stream closed + stream = g_string_new(""); + errno = 0; + gboolean received = FALSE; + while ((!received) && ((read_size = recv(client->sock, buf, 1, 0)) > 0)) { + printf("%c", buf[0]); + fflush(stdout); + g_string_append_len(stream, buf, read_size); + if (g_str_has_suffix(stream->str, END_STREAM)) { + received = TRUE; + } + memset(buf, 0, sizeof(buf)); + } + + // error + if (read_size == -1) { + perror("Error receiving on connection"); + xmppclient_end_session(client); + g_string_free(stream, TRUE); + break; + + // client closed + } else if (read_size == 0) { + printf("\n%s:%d - Client disconnected.\n", client->ip, client->port); + xmppclient_end_session(client); + g_string_free(stream, TRUE); + break; + + } else { + printf("\nEnd stream receieved"); + xmppclient_end_session(client); + break; + } } } } - - return 0; } int main(int argc , char *argv[]) @@ -167,8 +203,6 @@ int main(int argc , char *argv[]) printf("Starting on port: %d...\n", port); - clients_init(); - // create socket errno = 0; listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); // ipv4, tcp, ip @@ -198,29 +232,17 @@ int main(int argc , char *argv[]) } puts("Waiting for incoming connections..."); - // connection accept loop - while (1) { - c = sizeof(struct sockaddr_in); - errno = 0; - client_socket = accept(listen_socket, (struct sockaddr *)&client_addr, (socklen_t*)&c); - if (client_socket == -1) { - perror("Accept failed"); - } - - // create thread for each new client - ChatClient *client = clients_new(client_addr, client_socket); - clients_add(client); - - pthread_t client_thread; - ret = pthread_create(&client_thread, NULL, connection_handler, (void *)client); - if (ret == 0) { - printf("%s:%d - Connection handler assigned.\n", client->ip, client->port); - } else { - puts("Could not create thread."); - } - - clients_print_total(); + // connection accept + c = sizeof(struct sockaddr_in); + errno = 0; + client_socket = accept(listen_socket, (struct sockaddr *)&client_addr, (socklen_t*)&c); + if (client_socket == -1) { + perror("Accept failed"); + return 0; } + XMPPClient *client = xmppclient_new(client_addr, client_socket); + + connection_handler(client); return 0; } diff --git a/src/server/xmppclient.c b/src/server/xmppclient.c new file mode 100644 index 0000000..f578c5b --- /dev/null +++ b/src/server/xmppclient.c @@ -0,0 +1,32 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "server/xmppclient.h" + +XMPPClient* +xmppclient_new(struct sockaddr_in client_addr, int socket) +{ + XMPPClient *client = malloc(sizeof(XMPPClient)); + client->ip = strdup(inet_ntoa(client_addr.sin_addr)); + client->port = ntohs(client_addr.sin_port); + client->sock = socket; + client->nickname = NULL; + + return client; +} + +void +xmppclient_end_session(XMPPClient *client) +{ + close(client->sock); + + free(client->ip); + free(client->nickname); + free(client); +} diff --git a/src/server/xmppclient.h b/src/server/xmppclient.h new file mode 100644 index 0000000..9056540 --- /dev/null +++ b/src/server/xmppclient.h @@ -0,0 +1,16 @@ +#ifndef __H_XMPPCLIENT +#define __H_XMPPCLIENT + +#include + +typedef struct xmpp_client_t { + char *ip; + int port; + int sock; + char *nickname; +} XMPPClient; + +XMPPClient* xmppclient_new(struct sockaddr_in client_addr, int socket); +void xmppclient_end_session(XMPPClient *client); + +#endif