From 6a2c567b85be275bb431c09952a88ea4cdf210aa Mon Sep 17 00:00:00 2001 From: sotech117 Date: Mon, 25 Sep 2023 22:21:42 -0400 Subject: massive restrcuting of code for readability --- client.c | 100 +++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 56 insertions(+), 44 deletions(-) (limited to 'client.c') diff --git a/client.c b/client.c index df9f731..17a8a81 100644 --- a/client.c +++ b/client.c @@ -1,3 +1,12 @@ +/* + author: sotech117 + date: 9/25/2023 + course: csci1680 + description: client for snowcast, a music streaming service + + enjoy :) +*/ + #include #include #include @@ -12,53 +21,42 @@ #include #include "protocol.c" -#define MAX_READ_SIZE 1024 -#define LINE_MAX 1024 - -void *command_line_routine(void *args); +#define COMMAND_LINE_MAX 1024 +// handles the handshake and returns the number of stations u_int16_t handle_handshake(int sockfd, char* udpPort); -int station_is_set = 0; -int l = 0; -int waiting = 0; -int exiting = 0; - -// get sockaddr, IPv4 or IPv6: -void *get_in_addr(struct sockaddr *sa) -{ - if (sa->sa_family == AF_INET) { - return &(((struct sockaddr_in*)sa)->sin_addr); - } +// routine thread for the command line +void *command_line_routine(void *args); - return &(((struct sockaddr_in6*)sa)->sin6_addr); -} +int l = 0; // logging +int station_is_set = 0; // if we have a station set +int waiting = 0; // for command line "snowcast_control>" prompt to be a new lone +int exiting = 0; // to not have error messages when the program exits "gracefully" -int main(int argc, char *argv[]) +main(int argc, char *argv[]) // no int here for good luck :) { - int sockfd, numbytesrecv, numbytessent, recvbytes; - // char buf[MAXDATASIZE]; - struct addrinfo hints, *servinfo, *p; - char s[INET6_ADDRSTRLEN]; - - // check arugments + // CHECK AND USE ARGUMENTS + // ------------------------------------------------------------------------------------------------- if (argc != 4) { fprintf(stderr," \n"); exit(1); } + const char* tcpPort = argv[2]; // port we use to connect to server's tcp stream + const char* udpPort = argv[3]; // port we use to connect to server's udp info and command + // SETUP TCP CONNECTION (getaaadrinfo->socket->connect) + // ------------------------------------------------------------------------------------------------- + struct addrinfo hints, *servinfo, *p; memset(&hints, 0, sizeof hints); hints.ai_family = AF_INET; // only IPv4 hints.ai_socktype = SOCK_STREAM; - char* tcpPort = argv[2]; // port we use to connect to server's tcp stream - char* udpPort = argv[3]; // port we use to connect to server's udp info and command - - // resolve host - int rv; - if ((rv = getaddrinfo(argv[1], tcpPort, &hints, &servinfo)) != 0) + // resolve host & make socket + int sockfd, err; + if ((err = getaddrinfo(argv[1], tcpPort, &hints, &servinfo)) != 0) { - fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(err)); return 1; } // loop through all the results and connect to the first we can @@ -80,9 +78,12 @@ int main(int argc, char *argv[]) fprintf(stderr, "client: failed to connect\n"); return 2; } - inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), s, sizeof s); + // char s[INET_ADDRSTRLEN]; // for printing the ip address + // inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), s, sizeof s); freeaddrinfo(servinfo); // all done with this structure + // DO HANDSHAKE & PRINT STATION NUMBER + // ------------------------------------------------------------------------------------------------- // now that we're connectioned, let's do the handshake uint16_t num_stations = handle_handshake(sockfd, udpPort); @@ -92,17 +93,19 @@ int main(int argc, char *argv[]) printf("Welcome to Snowcast! The server has %u stations.\n", num_stations); fflush(stdout); - // start the thread to accept command lines + // START COMMAND LINE THREAD + // ------------------------------------------------------------------------------------------------- pthread_t command_line_thread; pthread_create(&command_line_thread, NULL, command_line_routine, (void*)sockfd); - // this while loop hangs on recv and runs when there is new data + // START WHILE LOOP THAT HANDLES ALL REPLIES + // ------------------------------------------------------------------------------------------------- while (69) { // get the type of the incoming reply uint8_t reply_type = -1; // print size of utin8 if (recv(sockfd, &reply_type, 1, 0) == -1) { - if (exiting) { + if (exiting) { // just to remove that pesky error message break; } perror("recv in first byte"); @@ -211,6 +214,9 @@ int main(int argc, char *argv[]) if (reply_type == STATIONSHUTDOWN) { // we are getting StationShutdown if (l) printf("received STATIONSHUTDOWN reply.\n"); + // remove timeout, in case we were waiting for an announce + remove_timeout(sockfd); + if (!waiting) printf("\n"); // note: this is worth the lines for a clean cmd prompt :) waiting = 0; @@ -251,27 +257,28 @@ int main(int argc, char *argv[]) return 0; } +/* thread for managing the command line */ void *command_line_routine(void* args) { // unpack sockfd as arg int sockfd = (int) args; // buffer for input - char input[LINE_MAX]; + char input[COMMAND_LINE_MAX]; printf("Enter a number to change to it's station. Enter q to end stream.\n"); printf("snowcast_control> "); fflush(stdout); while (420) { - memset(input, 0, LINE_MAX); - char *line = fgets(input, LINE_MAX, stdin); + memset(input, 0, COMMAND_LINE_MAX); + char *line = fgets(input, COMMAND_LINE_MAX, stdin); // nothing was typed if (line == NULL) { continue; } - // q command: exit the program - if (strncmp("q\n", input, LINE_MAX) == 0) { + // "q" command: exit the program + if (strncmp("q\n", input, COMMAND_LINE_MAX) == 0) { // end code if type in q exiting = 1; printf("Exiting.\n"); @@ -279,8 +286,8 @@ void *command_line_routine(void* args) { exit(0); } - // l command: STATIONINFO command (EXTRA CREDIT) - if (strncmp("l\n", input, LINE_MAX) == 0) { + // "l" command: STATIONINFO command (EXTRA CREDIT) + if (strncmp("l\n", input, COMMAND_LINE_MAX) == 0) { // send the command to list stations if (l) printf("sending LISTSTATIONS command. waiting for STATIONINFO reply.\n"); apply_timeout(sockfd); // apply a timeout, will be released when we get the reply @@ -292,8 +299,8 @@ void *command_line_routine(void* args) { continue; } - // log command: toggle logging - if (strncmp("log\n", input, LINE_MAX) == 0) + // "log" command: toggle logging + if (strncmp("log\n", input, COMMAND_LINE_MAX) == 0) { l = !l; printf("LOGGING is now %s!\n", l ? "on" : "off"); @@ -335,6 +342,11 @@ void *command_line_routine(void* args) { return (NULL); } +/* + handles the handshake, given the new socket fd and the udp port of this client + returns the number of stations + note: will close the program on failure! +*/ uint16_t handle_handshake(int sockfd, char* udp_port) { if (l) printf("found server, sending HELLO command.\n"); -- cgit v1.2.3-70-g09d2