aboutsummaryrefslogtreecommitdiff
path: root/client.c
diff options
context:
space:
mode:
Diffstat (limited to 'client.c')
-rw-r--r--client.c146
1 files changed, 91 insertions, 55 deletions
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