/* * vowelizer_client.cpp * * Author: Jett Penner * Date Created: February 15, 2022 * * Purpose: Created for CPSC441 W2022 Assignment 2 * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MAX_HOSTNAME_LENGTH 64 #define MAX_MESSAGE_LENGTH 400 #define NEXT_PORT 1 // Will host the UDP server on a port +1 higher than the input port number // Menu selections #define ALLDONE 0 #define SIMPLE_SPLIT 1 #define ADVANCED_SPLIT 2 #define BONUS_SPLIT 3 #define SUPER_BONUS_SPLIT 4 #define SIMPLE_MERGE 5 #define ADVANCED_MERGE 6 #define BONUS_MERGE 7 #define SUPER_BONUS_MERGE 8 #define MENU "9" #define ACK "ACK" // Main Program int main(int argc, char *argv[]) { // Declare variables for TCP port setup int port_tcp, port_udp, sockfd, bytes; char *p; char hostname[MAX_HOSTNAME_LENGTH], message_out[MAX_MESSAGE_LENGTH], message_back[MAX_MESSAGE_LENGTH]; struct sockaddr_in tcp_server; struct hostent *hp; // Declare variables for UDP port setup struct sockaddr_in si_server; struct sockaddr *udp_server; int s, index; unsigned int length = sizeof(si_server); char buf[MAX_MESSAGE_LENGTH], IP[MAX_HOSTNAME_LENGTH]; int readBytes; // Declare variables for the actual string functions int choice, len; char c; char message_consonants[MAX_MESSAGE_LENGTH], message_vowels[MAX_MESSAGE_LENGTH]; // Hard-coded functionality strcpy(hostname, "csx3.cpsc.ucalgary.ca"); // Set the hostname strcpy(IP, "136.159.5.27"); // Set the IP strcpy(message_out, MENU); // Initial message to send to TCP server strcpy(buf, ACK); // Initial message to send to UDP server // Handle the command line, set the port numbers if (argc < 2) { printf("No port specified. Please specify a port.\n"); exit(-1); } port_tcp = strtol(argv[1], &p, 0); port_udp = port_tcp + NEXT_PORT; printf("TCP port: %d\n", port_tcp); printf("UDP port: %d\n", port_udp); // Initialization of TCP server sockaddr data structure memset(&tcp_server, 0, sizeof(tcp_server)); tcp_server.sin_family = AF_INET; tcp_server.sin_port = htons(port_tcp); tcp_server.sin_addr.s_addr = htonl(INADDR_ANY); // Resolve the hostname hp = gethostbyname(hostname); if (hp == NULL) { fprintf(stderr, "Unknown host: %s\n", hostname); exit(1); } bcopy(hp->h_addr, &tcp_server.sin_addr, hp->h_length); // Create TCP client socket if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { fprintf(stderr, "socket() call failed for establishing initial TCP connection\n"); exit(1); } // Create UDP client socket if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { printf( "socket() call failed for establishing initial UDP connection\n"); return 1; } memset((char*) &si_server, 0, sizeof(si_server)); si_server.sin_family = AF_INET; si_server.sin_port = htons(port_udp); udp_server = (struct sockaddr*) &si_server; if (inet_pton(AF_INET, IP, &si_server.sin_addr) == 0) { printf("inet_pton() failed for UDP\n"); exit(1); } // Connect to server with TCP if (connect(sockfd, (struct sockaddr*) &tcp_server, sizeof(struct sockaddr_in)) == -1) { fprintf(stderr, "connect() call failed for establishing initial TCP connection\n"); exit(1); } // Send initial message via UDP to provide return port printf("Sending message to UDP: %s\n", buf); if (sendto(s, buf, strlen(buf), 0, udp_server, sizeof(si_server)) == -1) { printf("sendto() failed for initial UDP connection\n"); exit(1); } // Recieve initial message from UDP if ((readBytes = recvfrom(s, buf, MAX_MESSAGE_LENGTH, 0, udp_server, &length)) == -1) { printf("recvfrom() failed for initial UDP connection\n"); exit(1); } buf[readBytes] = '\0'; printf("Received message from UDP: %s\n", buf); // Send initial message to TCP printf("Sending message to TCP: %s\n", message_out); if (send(sockfd, message_out, sizeof(message_out), 0) == -1) { fprintf(stderr, "send() call failed for the first TCP message to server"); exit(1); } // Print the menu from TCP if ((bytes = recv(sockfd, message_back, sizeof(message_back), 0)) > 0) { message_back[bytes] = '\0'; printf("\n%s", message_back); } else { fprintf(stderr, "Server failed to return a message from getgo."); close(sockfd); exit(1); } // Get the choice from the user via TCP scanf("%d", &choice); while (choice != ALLDONE) { // Send the choice to the server via TCP memset(message_out, 0, sizeof(message_out)); memset(message_back, 0, sizeof(message_back)); message_out[0] = (char) choice + 48; message_out[1] = '\0'; if (send(sockfd, message_out, sizeof(message_out), 0) == -1) { fprintf(stderr, "send() call failed for the TCP choice to the server"); exit(1); } // Receive the acknowledgment from the server via TCP if ((bytes = recv(sockfd, message_back, sizeof(message_back), 0)) > 0) { message_back[bytes] = '\0'; printf("\n%s", message_back); } else { fprintf(stderr, "Server failed to return a message."); close(sockfd); exit(1); } // Perform function based on choice if (choice == SIMPLE_SPLIT || choice == ADVANCED_SPLIT || choice == BONUS_SPLIT || choice == SUPER_BONUS_SPLIT) { // Get the word for the server to split memset(message_out, 0, sizeof(message_out)); memset(message_back, 0, sizeof(message_back)); memset(buf, 0, sizeof(buf)); c = getchar(); len = 0; while ((c = getchar()) != '\n') { message_out[len] = c; len++; } message_out[len] = '\0'; // Send the word to the server if (send(sockfd, message_out, sizeof(message_out), 0) == -1) { fprintf(stderr, "send() call failed for the TCP message in split to server"); exit(1); } // Receive vowels message from UDP if ((readBytes = recvfrom(s, buf, MAX_MESSAGE_LENGTH, 0, udp_server, &length)) == -1) { printf("recvfrom() failed for UDP response to split\n"); exit(1); } buf[readBytes] = '\0'; printf("Received vowels via UDP: %s\n", buf); // Receive consonants message from TCP if ((bytes = recv(sockfd, message_back, sizeof(message_back), 0)) > 0) { message_back[bytes] = '\0'; printf("Received consonants via TCP: %s\n", message_back); } else { fprintf(stderr, "Server failed to return a message."); close(sockfd); exit(1); } } else if (choice == SIMPLE_MERGE || choice == ADVANCED_MERGE || choice == BONUS_MERGE || choice == SUPER_BONUS_MERGE) { // Get the consonants memset(message_consonants, 0, sizeof(message_consonants)); memset(buf, 0, sizeof(buf)); c = getchar(); len = 0; while ((c = getchar()) != '\n') { message_consonants[len] = c; len++; } message_consonants[len] = '\0'; // Get the vowels memset(message_vowels, 0, sizeof(message_vowels)); printf("Please insert the vowels string: "); len = 0; while ((c = getchar()) != '\n') { message_vowels[len] = c; len++; } message_vowels[len] = '\0'; // Send vowel message via UDP strcpy(buf, message_vowels); printf("Sending message to UDP: %s\n", buf); if (sendto(s, buf, strlen(buf), 0, udp_server, sizeof(si_server)) == -1) { printf("sendto() failed for UDP vowels\n"); exit(1); } // Send the word to the server if (send(sockfd, message_consonants, sizeof(message_consonants), 0) == -1) { fprintf(stderr, "send() call failed for the TCP message in merge to server"); exit(1); } if ((bytes = recv(sockfd, message_back, sizeof(message_back), 0)) > 0) { message_back[bytes] = '\0'; printf("\n%s", message_back); } else { fprintf(stderr, "Server failed to return a message."); close(sockfd); exit(1); } } // Code to restart loop memset(message_out, 0, sizeof(message_out)); memset(message_back, 0, sizeof(message_back)); strcpy(message_out, MENU); // Send initial message if (send(sockfd, message_out, sizeof(message_out), 0) == -1) { fprintf(stderr, "send() call failed for the loop TCP message to server for menu"); exit(1); } // Print the menu if ((bytes = recv(sockfd, message_back, sizeof(message_back), 0)) > 0) { message_back[bytes] = '\0'; printf("\n%s", message_back); } else { fprintf(stderr, "Server failed to return a message."); close(sockfd); exit(1); } // Get the choice from the user scanf("%d", &choice); } close(sockfd); close(s); printf("Program terminated.\n"); exit(0); }