From 2acabfaf7308be7517d948743cc6ab9660566327 Mon Sep 17 00:00:00 2001 From: sotech117 Date: Sun, 24 Sep 2023 01:53:43 -0400 Subject: add small fixes for cmd prompt and optimize --- client.c | 146 +++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 91 insertions(+), 55 deletions(-) (limited to 'client.c') diff --git a/client.c b/client.c index 288b50c..4ca1165 100644 --- a/client.c +++ b/client.c @@ -21,7 +21,12 @@ void *command_line_routine(void *args); +int 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) @@ -86,46 +91,15 @@ int main(int argc, char *argv[]) freeaddrinfo(servinfo); // all done with this structure - apply_timeout(sockfd); - - struct Hello hello; - hello.commandType = 0; - // convert updPort to an int - int udpPortInt = atoi(udpPort); - hello.udpPort = htons(udpPortInt); - if ((numbytessent = send(sockfd, &hello, sizeof(struct Hello), 0)) == -1) { - perror("send"); - exit(1); - } - - // recv the first byte of the message to get it's type - uint8_t reply_type = -1; - // print size of utin8 - if (recv(sockfd, &reply_type, 1, 0) == -1) { - perror("recv"); - exit(1); - } - - // recv the message, check for errors too - int16_t num_stations = -1; - int bytes_to_read = sizeof(uint16_t); - if (recv_all(sockfd, &num_stations, &bytes_to_read) == -1) { - perror("recv_all"); - exit(1); - } - - remove_timeout(sockfd); + uint16_t num_stations = handle_handshake(sockfd, udpPort); - num_stations = ntohs(num_stations); fflush(stdout); - printf("Welcome to Snowcast! The server has %d stations.\n", num_stations); + printf("Welcome to Snowcast! The server has %u stations.\n", num_stations); fflush(stdout); pthread_t command_line_thread; pthread_create(&command_line_thread, NULL, command_line_routine, (void*)sockfd); - - // CONSIDER: could recieve the welcome message here // int recvbytes; while (1) { @@ -133,19 +107,23 @@ int main(int argc, char *argv[]) uint8_t reply_type = -1; // print size of utin8 if (recv(sockfd, &reply_type, 1, 0) == -1) { - perror("recv"); + if (exiting) { + break; + } + perror("recv in first byte"); exit(1); } - if (reply_type == 2) { // we have a second welcome message + fprintf(stderr, "WECLOME reply received twice. Exiting.\n"); close(sockfd); exit(1); } if (reply_type == 3) { // we have an announce message + if (!station_is_set) { - fprintf(stderr, "ANNOUNCE received before SETSTATION command."); + fprintf(stderr, "ANNOUNCE reply received before SETSTATION command. Exiting.\n"); close(sockfd); exit(1); } @@ -153,7 +131,7 @@ int main(int argc, char *argv[]) // get the string size u_int8_t string_size = -1; if (recv(sockfd, &string_size, 1, 0) == -1) { - perror("recv"); + perror("recv in announce"); exit(1); } char *song_name = malloc(string_size); @@ -161,12 +139,15 @@ int main(int argc, char *argv[]) int bytes_to_read = string_size; if (recv_all(sockfd, song_name, &bytes_to_read) == -1) { - perror("recv_all"); + perror("recv_all in announce"); exit(1); } - remove_timeout(sockfd); + + if (!waiting) printf("\n", waiting); // note: this is worth the lines for a clean cmd prompt + waiting = 0; fflush(stdout); printf("New song announced: %s\n", song_name); + printf("snowcast_control> "); fflush(stdout); free(song_name); continue; @@ -174,46 +155,50 @@ int main(int argc, char *argv[]) // get the string size u_int8_t string_size = -1; if (recv(sockfd, &string_size, 1, 0) == -1) { - perror("recv"); + perror("recv in invalid"); exit(1); } char *message = malloc(string_size); if(message == NULL) { perror("malloc in message"); } int bytes_to_read = string_size; if (recv_all(sockfd, message, &bytes_to_read) == -1) { - perror("recv_all"); + perror("recv_all in invalid"); exit(1); } fflush(stdout); - printf("Invalid protocol: %s. Exiting.\n", message); + printf("received INVALID reply: %s.\nExiting.\n", message); fflush(stdout); free(message); close(sockfd); exit(1); } - else if (reply_type == 6) { // we station info + else if (reply_type == 6) { // we are getting STATIONINFO // get the string size uint8_t string_size = -1; if (recv(sockfd, &string_size, 1, 0) == -1) { - perror("recv"); + perror("recv in stationinfo"); exit(1); } char *info = malloc(string_size); if(info == NULL) { perror("malloc in info"); } int bytes_to_read = string_size; if (recv_all(sockfd, info, &bytes_to_read) == -1) { - perror("recv_all"); + perror("recv_all in station info"); exit(1); } remove_timeout(sockfd); + if (l) printf("received STATIONINFO reply.\n"); + fflush(stdout); printf("Station Information:\n%s\n", info); + printf("snowcast_control> "); fflush(stdout); + free(info); continue; } - printf("Lost connection to server. Exiting."); + printf("\nsocket to server HUNGUP. Exiting.\n"); close(sockfd); exit(1); } @@ -224,7 +209,10 @@ void *command_line_routine(void* args) { int sockfd = (int) args; char input[LINE_MAX]; - printf("Enter a number to change to it's station. Click q to end stream.\n"); + + printf("Enter a number to change to it's station. Enter q to end stream.\n"); + printf("snowcast_control> "); + fflush(stdout); while (1) { char *line = fgets(input, LINE_MAX, stdin); @@ -232,28 +220,39 @@ void *command_line_routine(void* args) { continue; } else if (strncmp("q\n", input, LINE_MAX) == 0) { // end code if type in q - printf("Exiting.\n"); - close(sockfd); - exit(0); - } - else if (strncmp("q\n", input, LINE_MAX) == 0) { - // end code if type in q + exiting = 1; printf("Exiting.\n"); close(sockfd); exit(0); } else if (strncmp("l\n", input, LINE_MAX) == 0) { // send the command to list stations + if (l) printf("sending LISTSTATIONS command. waiting for STATIONINFO reply.\n"); apply_timeout(sockfd); int list_station_reply_type = 5; if (send(sockfd, &list_station_reply_type, 1, 0) == -1) { perror("send"); exit(1); } - } else { + } else if (strncmp("log\n", input, LINE_MAX) == 0) { + l = !l; + printf("LOGGING is now %s!\n", l ? "on" : "off"); + printf("snowcast_control> "); + fflush(stdout); + } + else { // convert input to an int int inputInt = atoi(input); + if (input[0] != '0' && inputInt == 0) { + printf("unknown command\n"); + printf("snowcast_control> "); + fflush(stdout); + continue; + } // printf("Changing to station %d.\n", inputInt); + // set waiting so no new line on announce + waiting = 1; + // send the command to change the station apply_timeout(sockfd); struct SetStation setStation; @@ -270,6 +269,43 @@ void *command_line_routine(void* args) { } } } - return (NULL); +} + +int handle_handshake(int sockfd, char* udp_port) { + apply_timeout(sockfd); + + if (l) printf("found server, sending HELLO command. waiting for ANNOUNCE reply.\n"); + + struct Hello hello; + hello.commandType = 0; + // convert updPort to an int + int udp_port_int = atoi(udp_port); + hello.udpPort = htons(udp_port_int); + if (send(sockfd, &hello, sizeof(struct Hello), 0) == -1) { + perror("send"); + exit(1); + } + + // recv the first byte of the message to get it's type + uint8_t reply_type = -1; + // print size of utin8 + if (recv(sockfd, &reply_type, 1, 0) == -1) { + perror("recv in handshake"); + exit(1); + } + + // recv the message, check for errors too + int16_t num_stations = -1; + int bytes_to_read = sizeof(uint16_t); + if (recv_all(sockfd, &num_stations, &bytes_to_read) == -1) { + perror("recv_all in handshake"); + exit(1); + } + + if (l) printf("received ANNOUNCE reply.\n"); + + remove_timeout(sockfd); + + return ntohs(num_stations); } \ No newline at end of file -- cgit v1.2.3-70-g09d2