💾 Archived View for gmi.noulin.net › gitRepositories › spartserv › file › spartclientudp.c.gmi captured on 2023-11-04 at 13:02:06. Gemini links have been rewritten to link to archived content

View Raw

More Information

-=-=-=-=-=-=-

spartserv

Log

Files

Refs

README

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