diff options
author | sotech117 <michael_foiani@brown.edu> | 2023-09-20 23:24:05 -0400 |
---|---|---|
committer | sotech117 <michael_foiani@brown.edu> | 2023-09-20 23:24:05 -0400 |
commit | 3d9c7d4c5ae135ace068ba50f6b3ae971d8e276b (patch) | |
tree | 5e391492380af5fb351d543d8fd6b17ad5871afe | |
parent | 362250d1cb923d9ced8ea51508ace50b76050b06 (diff) |
implement collecting all bits, if they don't come in one message
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | client.c | 90 | ||||
-rw-r--r-- | protocol.c | 40 | ||||
-rw-r--r-- | protocol.h | 8 | ||||
-rw-r--r-- | server.c (renamed from snowcast_server_concurrent.c) | 70 | ||||
-rwxr-xr-x | snowcast_control | bin | 35357 -> 35565 bytes | |||
-rw-r--r-- | snowcast_control.dSYM/Contents/Resources/DWARF/snowcast_control | bin | 13757 -> 14770 bytes | |||
-rwxr-xr-x | snowcast_listener | bin | 34654 -> 34654 bytes | |||
-rwxr-xr-x | snowcast_server | bin | 55868 -> 56124 bytes | |||
-rw-r--r-- | snowcast_server.dSYM/Contents/Resources/DWARF/snowcast_server | bin | 26569 -> 27185 bytes |
10 files changed, 151 insertions, 59 deletions
@@ -5,7 +5,7 @@ CFLAGS = -g -I. -std=gnu99 -Wall -pthread all: server client server: - $(CC) $(CFLAGS) -o snowcast_server snowcast_server_concurrent.c + $(CC) $(CFLAGS) -o snowcast_server server.c client: $(CC) $(CFLAGS) -o snowcast_control client.c @@ -16,7 +16,7 @@ #include <arpa/inet.h> -#include "protocol.h" +#include "protocol.c" #define MAXDATASIZE 100 // max number of bytes we can get at once @@ -103,6 +103,9 @@ int main(int argc, char *argv[]) exit(1); } + // CONSIDER: could recieve the welcome message here + + char input[LINE_MAX]; printf("Enter a number to change to it's station. Click q to end stream.\n"); while (1) { @@ -123,8 +126,9 @@ int main(int argc, char *argv[]) struct SetStation setStation; setStation.commandType = 1; setStation.stationNumber = htons(inputInt); - if ((numbytessent = send(sockfd, &setStation, sizeof(struct SetStation), 0)) == -1) { - perror("send"); + int bytes_to_send = sizeof(struct SetStation); + if (send_all(sockfd, &setStation, &bytes_to_send) == -1) { + perror("send_all"); exit(1); } } @@ -135,59 +139,65 @@ int main(int argc, char *argv[]) void *reply_thread_routine(void* args) { int sockfd = (int)args; - int recvbytes; - char buf[MAX_READ_SIZE]; + // int recvbytes; while (1) { - // recv the message, check for errors too - memset(buf, 0, MAX_READ_SIZE); - if ((recvbytes = recv(sockfd, &buf, MAX_READ_SIZE, 0)) == -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); } - buf[recvbytes] = '\0'; - // printf("client: received %d bytes on a reply call \n", recvbytes); - // print the two first field of the call - // printf("client: replyType: %d, stringSize: %d\n", buf[0], buf[1]); - // print the while buffer by char - // for (int i = 0; i < recvbytes; i++) { - // printf("%c ", buf[i]); - // } - struct Reply reply; - memcpy(&reply, buf, 2); - - // print out the fields of reply on one line - // printf("\nclient: replyType: %d, stringSize: %d\n", reply.replyType, reply.stringSize); - if (reply.replyType == 2) { - struct Welcome msg; + if (reply_type == 2) { // we have a welcome message // recv the message, check for errors too - memcpy(&msg, buf, sizeof(struct Welcome)); - msg.numStations = ntohs(msg.numStations); - printf("Welcome to Snowcast! The server has %d stations.\n", msg.numStations); + 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); + } + num_stations = ntohs(num_stations); + printf("Welcome to Snowcast! The server has %d stations.\n", num_stations); continue; } - // print the size of reply - if (reply.replyType == 3) { - // printf("client: received an announce message\n"); - - char *song_name = malloc(reply.stringSize); - // printf(sizeof(struct Reply)); - memcpy(song_name, buf + 2, reply.stringSize); + if (reply_type == 3) { // we have an announce message + // get the string size + u_int8_t string_size = -1; + if (recv(sockfd, &string_size, 1, 0) == -1) { + perror("recv"); + exit(1); + } + char *song_name = malloc(string_size); + int bytes_to_read = string_size; + if (recv_all(sockfd, song_name, &bytes_to_read) == -1) { + perror("recv_all"); + exit(1); + } printf("New song announced: %s\n", song_name); free(song_name); continue; - } else if (reply.replyType == 4) { - // print sockfd - char *message = malloc(reply.stringSize); - // printf(sizeof(struct Reply)); - memcpy(message, buf + 2, reply.stringSize); - printf("Exiting. %s\n", message); + } else if (reply_type == 4) { // we have an invalid command message + // get the string size + u_int8_t string_size = -1; + if (recv(sockfd, &string_size, 1, 0) == -1) { + perror("recv"); + exit(1); + } + char *message = malloc(string_size); + int bytes_to_read = string_size; + if (recv_all(sockfd, message, &bytes_to_read) == -1) { + perror("recv_all"); + exit(1); + } + printf("Invalid protocol: %s. Exiting.\n", message); + free(message); close(sockfd); exit(1); } - printf("Exiting. Lost connection to server."); + printf("Lost connection to server. Exiting."); close(sockfd); exit(1); } diff --git a/protocol.c b/protocol.c new file mode 100644 index 0000000..864afd8 --- /dev/null +++ b/protocol.c @@ -0,0 +1,40 @@ +#include <sys/types.h> +#include <sys/socket.h> + +#include "protocol.h" + +int send_all(int sock, char *buf, int *len) +{ + int total = 0; // how many bytes we've sent + int bytesleft = *len; // how many we have left to send + int n; + + while(total < *len) { + n = send(sock, buf+total, bytesleft, 0); + if (n == -1) { break; } + total += n; + bytesleft -= n; + } + + *len = total; // return number actually sent here + + return n==-1?-1:0; // return -1 on failure, 0 on success +} + +int recv_all(int sock, char *buf, int *len) +{ + int total = 0; // how many bytes we've sent + int bytesleft = *len; // how many we have left to send + int n; + + while(total < *len) { + n = recv(sock, buf+total, bytesleft, 0); + if (n == -1) { break; } + total += n; + bytesleft -= n; + } + + *len = total; // return number actually sent here + + return n==-1?-1:0; // return -1 on failure, 0 on success +} @@ -25,8 +25,7 @@ struct Welcome { struct Reply { uint8_t replyType; uint8_t stringSize; - char *string; -} __attribute__((packed)); +} reply_t __attribute__((packed)); struct Announce { uint8_t replyType; uint8_t songnameSize; @@ -36,4 +35,7 @@ struct InvalidCommand { uint8_t replyType; uint8_t replyStringSize; char *replyString; -} __attribute__((packed));
\ No newline at end of file +} __attribute__((packed)); + +int send_all(int sock, char *buf, int *len); +int recv_all(int sock, char *buf, int *len); diff --git a/snowcast_server_concurrent.c b/server.c index e0552cf..837432a 100644 --- a/snowcast_server_concurrent.c +++ b/server.c @@ -12,8 +12,7 @@ #include <fcntl.h> #include <sys/types.h> - -#include "protocol.h" +#include "protocol.c" #define LINE_MAX 1024 #define MAX_USERS 1000 @@ -72,7 +71,6 @@ 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 *load_file(void* arg); int main(int argc, char *argv[]) @@ -226,7 +224,7 @@ void *print_info_routine(void *arg) { return (NULL); } -int sendall(int udp_sockfd, char *buf, int *len, struct addrinfo *thread_res) +int send_all_udp(int udp_sockfd, char *buf, int *len, struct addrinfo *thread_res) { int MAX_PACKET_SIZE = 512; int total = 0; // how many bytes we've sent @@ -358,9 +356,9 @@ void *send_udp_packet_routine(void *arg) { // printf("size of file_buffer: %lu\n", sizeof(file_buffer)); int bytes_sent = sizeof(file_buffer); - if (sendall(udp_sockfd, file_buffer, &bytes_sent, thread_res) == -1) + if (send_all_udp(udp_sockfd, file_buffer, &bytes_sent, thread_res) == -1) { - perror("sendall"); + perror("send_all_udp"); printf("We only sent %d bytes because of the error!\n", bytes_sent); } // printf("We sent all %d bytes!\n", bytes_sent); @@ -587,9 +585,9 @@ void *select_thread(void *arg) { struct Welcome welcome; welcome.replyType = 2; welcome.numStations = htons(num_stations); - int numbytes; - if ((numbytes=send(i, &welcome, sizeof(struct Welcome), 0)) == -1) - perror("send"); + int bytes_to_send = sizeof(struct Welcome); + if (send_all(i, &welcome, &bytes_to_send) == -1) + perror("send_all"); } else if (command.commandType == 1) { // check if user has a udpPort @@ -742,11 +740,11 @@ void send_announce_reply(int fd, int station_num) { // printf("buffer: %s\n", send_buffer); - int bytessent; - if ((bytessent = send(fd, send_buffer, len_file_path + 2, 0)) == -1) - perror("send"); + size_t bytes_to_send = len_file_path + 2; + if (send_all(fd, send_buffer, &bytes_to_send) == -1) + perror("send_all"); // print the number of bytes sent - // printf("sent %d bytes\n", bytessent); + // printf("sent %d bytes\n", bytes_to_send); free(send_buffer); } @@ -766,8 +764,8 @@ void send_invalid_command_reply(int fd, size_t message_size, char* message) { // printf("buffer: %s\n", send_buffer); - int bytessent; - if ((bytessent = send(fd, send_buffer, message_size + 2, 0)) == -1) + int bytes_to_send = message_size + 2; + if (send_all(fd, send_buffer, &bytes_to_send) == -1) perror("send"); // print the number of bytes sent // printf("sent %d bytes\n", bytessent); @@ -789,3 +787,45 @@ int parse(char buffer[LINE_MAX], char *tokens[LINE_MAX / 2]) { return 1; } + +// int send_all(int s, char *buf, int *len) +// { +// int total = 0; // how many bytes we've sent +// int bytesleft = *len; // how many we have left to send +// int n; + +// while(total < *len) { +// n = send(s, buf+total, bytesleft, 0); +// if (n == -1) { break; } +// total += n; +// bytesleft -= n; +// } + +// *len = total; // return number actually sent here + +// return n==-1?-1:0; // return -1 on failure, 0 on success +// } + +// int recv_all(int sock, char *buffer, int total_size) +// { +// int total_bytes_read = 0; +// int to_read = total_size; + +// char *ptr = buffer; + +// while (to_read > 0) { +// int bytes_read = recv(sock, ptr, to_read, 0); +// if (bytes_read <= 0) { +// if (bytes_read != 0) { +// perror("recv"); +// } +// return -1; +// } + +// to_read -= bytes_read; +// ptr += bytes_read; +// total_bytes_read += bytes_read; +// } + +// return total_bytes_read; +// } diff --git a/snowcast_control b/snowcast_control Binary files differindex d4a3ba1..df78cdb 100755 --- a/snowcast_control +++ b/snowcast_control diff --git a/snowcast_control.dSYM/Contents/Resources/DWARF/snowcast_control b/snowcast_control.dSYM/Contents/Resources/DWARF/snowcast_control Binary files differindex d16a61e..c9e1f06 100644 --- a/snowcast_control.dSYM/Contents/Resources/DWARF/snowcast_control +++ b/snowcast_control.dSYM/Contents/Resources/DWARF/snowcast_control diff --git a/snowcast_listener b/snowcast_listener Binary files differindex 414117f..7f0e6a4 100755 --- a/snowcast_listener +++ b/snowcast_listener diff --git a/snowcast_server b/snowcast_server Binary files differindex 3434c81..918f71e 100755 --- a/snowcast_server +++ b/snowcast_server diff --git a/snowcast_server.dSYM/Contents/Resources/DWARF/snowcast_server b/snowcast_server.dSYM/Contents/Resources/DWARF/snowcast_server Binary files differindex d18b1e8..3f0a8c4 100644 --- a/snowcast_server.dSYM/Contents/Resources/DWARF/snowcast_server +++ b/snowcast_server.dSYM/Contents/Resources/DWARF/snowcast_server |