Home | History | Annotate | Download | only in network_server
      1 /* This is a simple TCP client that connects to port 1234 and prints a list
      2  * of files in a given directory.
      3  *
      4  * It directly deserializes and serializes messages from network, minimizing
      5  * memory use.
      6  *
      7  * For flexibility, this example is implemented using posix api.
      8  * In a real embedded system you would typically use some other kind of
      9  * a communication and filesystem layer.
     10  */
     11 
     12 #include <sys/socket.h>
     13 #include <sys/types.h>
     14 #include <netinet/in.h>
     15 #include <unistd.h>
     16 #include <dirent.h>
     17 #include <stdio.h>
     18 #include <string.h>
     19 
     20 #include <pb_encode.h>
     21 #include <pb_decode.h>
     22 
     23 #include "fileproto.pb.h"
     24 #include "common.h"
     25 
     26 bool printfile_callback(pb_istream_t *stream, const pb_field_t *field, void **arg)
     27 {
     28     FileInfo fileinfo;
     29 
     30     if (!pb_decode(stream, FileInfo_fields, &fileinfo))
     31         return false;
     32 
     33     printf("%-10lld %s\n", (long long)fileinfo.inode, fileinfo.name);
     34 
     35     return true;
     36 }
     37 
     38 bool listdir(int fd, char *path)
     39 {
     40     ListFilesRequest request;
     41     ListFilesResponse response;
     42     pb_istream_t input = pb_istream_from_socket(fd);
     43     pb_ostream_t output = pb_ostream_from_socket(fd);
     44     uint8_t zero = 0;
     45 
     46     if (path == NULL)
     47     {
     48         request.has_path = false;
     49     }
     50     else
     51     {
     52         request.has_path = true;
     53         if (strlen(path) + 1 > sizeof(request.path))
     54         {
     55             fprintf(stderr, "Too long path.\n");
     56             return false;
     57         }
     58 
     59         strcpy(request.path, path);
     60     }
     61 
     62     if (!pb_encode(&output, ListFilesRequest_fields, &request))
     63     {
     64         fprintf(stderr, "Encoding failed.\n");
     65         return false;
     66     }
     67 
     68     /* We signal the end of request with a 0 tag. */
     69     pb_write(&output, &zero, 1);
     70 
     71     response.file.funcs.decode = &printfile_callback;
     72 
     73     if (!pb_decode(&input, ListFilesResponse_fields, &response))
     74     {
     75         fprintf(stderr, "Decode failed: %s\n", PB_GET_ERROR(&input));
     76         return false;
     77     }
     78 
     79     if (response.path_error)
     80     {
     81         fprintf(stderr, "Server reported error.\n");
     82         return false;
     83     }
     84 
     85     return true;
     86 }
     87 
     88 int main(int argc, char **argv)
     89 {
     90     int sockfd;
     91     struct sockaddr_in servaddr;
     92     char *path = NULL;
     93 
     94     if (argc > 1)
     95         path = argv[1];
     96 
     97     sockfd = socket(AF_INET, SOCK_STREAM, 0);
     98 
     99     memset(&servaddr, 0, sizeof(servaddr));
    100     servaddr.sin_family = AF_INET;
    101     servaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    102     servaddr.sin_port = htons(1234);
    103 
    104     if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0)
    105     {
    106         perror("connect");
    107         return 1;
    108     }
    109 
    110     if (!listdir(sockfd, path))
    111         return 2;
    112 
    113     close(sockfd);
    114 
    115     return 0;
    116 }
    117