ex3_client.c (3472B)
1 #include <sys/socket.h> 2 #include <sys/types.h> 3 #include <sys/un.h> 4 5 #include <arpa/inet.h> 6 #include <netdb.h> 7 #include <netinet/in.h> 8 9 #include <err.h> 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <string.h> 13 #include <unistd.h> 14 15 /* 16 * Εργαστήριο ΛΣ2 (Δ6) / Εργασία 2: Άσκηση 3 (client) / 2020-2021 17 * Ονοματεπώνυμο: Χρήστος Μαργιώλης 18 * ΑΜ: 19390133 19 * Τρόπος μεταγλώττισης: `cc ex3_client.c -o ex3_client` 20 */ 21 22 /* Results from server. */ 23 struct pack_res { 24 char str[32]; 25 float avg; 26 }; 27 28 static void *emalloc(size_t nb); 29 static void usage(void); 30 31 static char *argv0; 32 33 static void * 34 emalloc(size_t nb) 35 { 36 void *p; 37 38 if ((p = malloc(nb)) == NULL) 39 err(1, "malloc"); 40 41 return p; 42 } 43 44 static void 45 usage(void) 46 { 47 fprintf(stderr, "usage: %1$s [-s sockfile]\n" 48 " %1$s -i [-p port] [-s sockfile] hostname\n" 49 " %1$s -i [-p port] [-s sockfile] ipv4_addr\n", argv0); 50 exit(1); 51 } 52 53 /* Code shared with `ex3_server` is explained in `ex3_server.c`. */ 54 int 55 main(int argc, char *argv[]) 56 { 57 struct pack_res *res; 58 struct sockaddr_un sun; 59 struct sockaddr_in sin; 60 struct hostent *hp; 61 char *sockfile = "/tmp/cool.sock"; 62 int *arr; 63 int fd, i, n, rc; 64 int port = 9999; 65 int iflag, uflag; 66 char ch; 67 68 argv0 = *argv; 69 uflag = 1; 70 iflag = 0; 71 72 while ((ch = getopt(argc, argv, "ip:s:")) != -1) { 73 switch (ch) { 74 case 'i': 75 iflag = 1; 76 uflag = 0; 77 break; 78 case 'p': 79 if ((port = atoi(optarg)) < 1024) 80 errx(1, "can't use port number < 1024"); 81 break; 82 case 's': 83 sockfile = optarg; 84 break; 85 case '?': 86 default: 87 usage(); 88 } 89 } 90 argc -= optind; 91 argv += optind; 92 93 if (iflag && argc < 1) 94 usage(); 95 96 if (iflag) { 97 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) 98 err(1, "socket(AF_INET)"); 99 (void)memset(&sin, 0, sizeof(sin)); 100 sin.sin_family = AF_INET; 101 sin.sin_port = htons(port); 102 if (!inet_aton(*argv, &sin.sin_addr)) { 103 if ((hp = gethostbyname(*argv)) == NULL) 104 errx(1, "gethostbyname(%s) failed", *argv); 105 (void)memcpy(&sin.sin_addr, hp->h_addr, hp->h_length); 106 } 107 if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) 108 err(1, "connect"); 109 } else if (uflag) { 110 if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) 111 err(1, "socket(AF_UNIX)"); 112 (void)memset(&sun, 0, sizeof(sun)); 113 sun.sun_family = AF_UNIX; 114 (void)strncpy(sun.sun_path, sockfile, sizeof(sun.sun_path) - 1); 115 116 if (connect(fd, (struct sockaddr *)&sun, sizeof(sun)) < 0) 117 err(1, "connect"); 118 } 119 120 res = emalloc(sizeof(struct pack_res)); 121 122 for (;;) { 123 /* Remove any previous junk. */ 124 (void)memset(res, 0, sizeof(struct pack_res)); 125 126 /* Make sure we send valid input to the server */ 127 do { 128 printf("\r%s> n: ", argv0); 129 rc = scanf("%d", &n); 130 (void)getchar(); 131 } while (rc != 1); 132 arr = emalloc(n * sizeof(int)); 133 for (i = 0; i < n; i++) { 134 do { 135 printf("\r%s> arr[%d]: ", argv0, i); 136 rc = scanf("%d", &arr[i]); 137 (void)getchar(); 138 } while (rc != 1); 139 } 140 if (send(fd, &n, sizeof(int), 0) < 0) 141 err(1, "send"); 142 if (send(fd, arr, n * sizeof(int), 0) < 0) 143 err(1, "send"); 144 if (recv(fd, res, sizeof(struct pack_res), 0) < 0) 145 err(1, "recv"); 146 free(arr); 147 148 printf("server response: %s\tavg: %.2f\n", res->str, res->avg); 149 do 150 printf("\r%s> continue (y/n)? ", argv0); 151 while ((ch = getchar()) != 'y' && ch != 'n'); 152 if (send(fd, &ch, 1, 0) < 0) 153 err(1, "send"); 154 if (ch == 'n') 155 break; 156 } 157 free(res); 158 (void)close(fd); 159 160 return 0; 161 }