From c055294629f1c3bb8843c65ce5ebff15efc94b7b Mon Sep 17 00:00:00 2001 From: sotech117 Date: Sat, 23 Sep 2023 23:10:12 -0400 Subject: implement extra credit --- client.c | 38 ++++++++++++++++++++++++++++++++++++++ protocol.h | 31 +++++++++++++++++-------------- server.c | 33 +++++++++++++++++++++++++++++++++ snowcast_control | Bin 18672 -> 35069 bytes snowcast_listener | Bin 13656 -> 34270 bytes snowcast_server | Bin 28792 -> 54332 bytes util/run_tests | 4 ++-- 7 files changed, 90 insertions(+), 16 deletions(-) diff --git a/client.c b/client.c index 06adbb1..63f7ef2 100644 --- a/client.c +++ b/client.c @@ -136,6 +136,9 @@ int main(int argc, char *argv[]) perror("recv"); exit(1); } + + + printf("reply_type: %d\n", reply_type); if (reply_type == 2) { // we have a welcome message close(sockfd); @@ -191,6 +194,27 @@ int main(int argc, char *argv[]) close(sockfd); exit(1); } + else if (reply_type == 6) { // we station info + // get the string size + uint8_t string_size = -1; + if (recv(sockfd, &string_size, 1, 0) == -1) { + perror("recv"); + 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"); + exit(1); + } + // remove_timeout(sockfd); + fflush(stdout); + printf("Station Information:\n%s\n", info); + fflush(stdout); + free(info); + continue; + } printf("Lost connection to server. Exiting."); close(sockfd); @@ -214,6 +238,20 @@ void *command_line_routine(void* args) { printf("Exiting.\n"); close(sockfd); exit(0); + } + 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("l\n", input, LINE_MAX) == 0) { + // send the command to list stations + // apply_timeout(sockfd); + int list_station_reply_type = 5; + if (send(sockfd, &list_station_reply_type, 1, 0) == -1) { + perror("send"); + exit(1); + } } else { // convert input to an int int inputInt = atoi(input); diff --git a/protocol.h b/protocol.h index aeeaa54..33ffb07 100644 --- a/protocol.h +++ b/protocol.h @@ -2,40 +2,43 @@ // client to server messages (commands) -struct Command { - uint8_t commandType; - uint16_t number; -} __attribute__((packed)); - struct Hello { - uint8_t commandType; + uint8_t commandType; // 0 uint16_t udpPort; } __attribute__((packed)); struct SetStation { - uint8_t commandType; + uint8_t commandType; // 1 uint16_t stationNumber; } __attribute__((packed)); +struct ListStations { + uint8_t commandType; // 5 +} __attribute__((packed)); + // server to client message (replies) struct Welcome { - uint8_t replyType; + uint8_t replyType; // 2 uint16_t numStations; } __attribute__((packed)); -struct Reply { - uint8_t replyType; - uint8_t stringSize; -} reply_t __attribute__((packed)); struct Announce { - uint8_t replyType; + uint8_t replyType; // 3 uint8_t songnameSize; char *songname; } __attribute__((packed)); + struct InvalidCommand { - uint8_t replyType; + uint8_t replyType; // 4 uint8_t replyStringSize; char *replyString; } __attribute__((packed)); +struct StationInfo { + uint8_t replyType; // 6 + uint8_t infoStringSize; + char *infoString; +} __attribute__((packed)); + + int send_all(int sock, char *buf, int *len); int recv_all(int sock, char *buf, int *len); diff --git a/server.c b/server.c index ccde0bb..d782bc0 100644 --- a/server.c +++ b/server.c @@ -92,6 +92,7 @@ void destroy_user(int sockfd); void send_announce_reply(int fd, int station_num); void send_invalid_command_reply(int fd, size_t message_size, char* message); +void send_stations_info_reply(int fd); // void *load_file(void* arg); @@ -711,6 +712,9 @@ void *select_routine(void *arg) { update_user_station(i, station_number); send_announce_reply(i, station_number); } + else if (command_type == 5) { // we got a ListStations command + send_stations_info_reply(i); + } else { // send back in invalid command char * message = "invalid command"; @@ -848,6 +852,35 @@ void send_invalid_command_reply(int fd, size_t message_size, char* message) { free(send_buffer); } +void send_stations_info_reply(int fd) { + printf("sending stations info reply\n"); + // get the size of the reply + + uint8_t reply_size = 0; + for (int i = 0; i < num_stations; i++) reply_size += snprintf(NULL, 0, "%d,%s\n", i, stations[i].filePath); + reply_size--; // don't want final \n + + // send type + uint8_t reply_num = 6; + if (send(fd, &reply_num, 1, 0) == -1) + perror("send in send stations info"); + // send payload size + printf("reply_size (server): %d\n", reply_size); + if (send(fd, &reply_size, 1, 0) == -1) + perror("send in send stations info"); + + char send_buffer[reply_size]; + int ptr = 0; + for (int i = 0; i < num_stations; i++) + ptr += sprintf(send_buffer + ptr, (i == num_stations - 1) ? "%d,%s" : "%d,%s\n", i, stations[i].filePath); + + printf("buffer: \n%s\n", send_buffer); + + int bytes_to_send = reply_size; // don't want final \n + if (send_all(fd, &send_buffer, &bytes_to_send) == -1) + perror("send_all"); +} + // Parses a buffer into tokens, from cs33 :) int parse(char buffer[LINE_MAX], char *tokens[LINE_MAX / 2]) { const char *regex = " \n\t\f\r"; diff --git a/snowcast_control b/snowcast_control index f1c54f0..a466c54 100755 Binary files a/snowcast_control and b/snowcast_control differ diff --git a/snowcast_listener b/snowcast_listener index f27a5c1..d15c2ac 100755 Binary files a/snowcast_listener and b/snowcast_listener differ diff --git a/snowcast_server b/snowcast_server index d383b01..3bab54f 100755 Binary files a/snowcast_server and b/snowcast_server differ diff --git a/util/run_tests b/util/run_tests index 64bbb1e..66a1063 100755 --- a/util/run_tests +++ b/util/run_tests @@ -105,8 +105,8 @@ do_milestone() { do_all() { - do_server $@ || true - do_control $@ + do_control $@ || true + do_server $@ } main() { -- cgit v1.2.3-70-g09d2