💾 Archived View for gmi.noulin.net › gitRepositories › spartserv › file › spartclientudp.c.gmi captured on 2024-08-18 at 18:52:55. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-11-04)
-=-=-=-=-=-=-
spartclientudp.c (2518B)
1 // Usage: spartclient hostname port path 2 #include <stdio.h> 3 #include <sys/types.h> 4 #include <sys/socket.h> 5 #include <netdb.h> 6 #include <netinet/in.h> 7 #include <string.h> 8 #include <stdlib.h> 9 #include <ctype.h> 10 #include <unistd.h> 11 12 int64_t parseInt(const char *string) { 13 while (!isdigit(*string) && *string != '-' && *string != 0) { 14 string++; 15 } 16 int64_t r = strtoll(string, NULL, 10); 17 return(r); 18 } 19 20 int main(int ac, char **av){ 21 int sock; 22 struct sockaddr_in server; 23 struct hostent *hp; 24 int mysock; 25 char buf[65536] = {0}; 26 int rval; 27 int i; 28 29 if (ac < 4) { 30 puts("Usage: spartclient hostname port path"); 31 return 0; 32 } 33 34 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 35 if (sock < 0){ 36 perror("Failed to create socket"); 37 } 38 39 server.sin_family = AF_INET; 40 41 hp = gethostbyname(av[1]); 42 if (hp==0) { 43 perror("gethostbyname failed"); 44 close(sock); 45 exit(1); 46 } 47 48 memcpy(&server.sin_addr, hp->h_addr, hp->h_length); 49 50 int64_t port = parseInt(av[2]); 51 52 if (port < 1 || port > 65000) { 53 printf("Invalid port %d.\n", port); 54 return 1; 55 } 56 57 server.sin_port = htons(port); 58 59 // open socket for response 60 struct sockaddr_in respaddr; 61 int rsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 62 if (rsock < 0){ 63 perror("Failed to create socket"); 64 } 65 66 respaddr.sin_family = AF_INET; 67 respaddr.sin_addr.s_addr = INADDR_ANY; 68 respaddr.sin_port = htons(port); 69 70 if (bind(rsock, (struct sockaddr *) &respaddr, sizeof(respaddr))){ 71 perror("bind failed"); 72 exit(1); 73 } 74 75 // build request 76 size_t len = strlen(av[1]); 77 memcpy(buf, av[1], len); 78 buf[len] = ' '; 79 char *cursor = buf + len + 1; 80 len = strlen(av[3]); 81 memcpy(cursor, av[3], len); 82 memcpy(cursor + len, " 0\r\n", strlen(" 0\r\n")); 83 cursor += len + strlen(" 0\r\n"); 84 85 // send request 86 if (sendto(sock, buf, cursor - buf, 0, (const struct sockaddr *)&server, sizeof(server)) < 0) { 87 perror("send failed"); 88 close(sock); 89 exit(1); 90 } 91 close(sock); 92 93 // reveice server response 94 struct sockaddr_in addr; 95 socklen_t ln = sizeof(addr); 96 rval = recvfrom(rsock, buf, sizeof(buf)-1/* -1 to add end of string before printing */, 0, (struct sockaddr *) &addr, &ln); 97 close(rsock); 98 if (addr.sin_addr.s_addr == server.sin_addr.s_addr && rval != -1 && rval != 0) { 99 buf[rval] = 0; 100 puts(buf); 101 } 102 } 103