diff options
author | Petteri Aimonen <jpa@npb.mail.kapsi.fi> | 2011-08-22 15:22:41 +0000 |
---|---|---|
committer | Petteri Aimonen <jpa@npb.mail.kapsi.fi> | 2011-08-22 15:22:41 +0000 |
commit | 494fbd91e4e5574a4cf8dbe69b3f80a08e97e85b (patch) | |
tree | bdcd9d84aecda89d3af602c8ffccb9ffa5518561 /example/client.c | |
parent | 7f53c3f7484679c1e38607f59542d43be1387650 (diff) |
example client
git-svn-id: https://svn.kapsi.fi/jpa/nanopb@958 e3a754e5-d11d-0410-8d38-ebb782a927b9
Diffstat (limited to 'example/client.c')
-rw-r--r-- | example/client.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/example/client.c b/example/client.c new file mode 100644 index 00000000..f0520574 --- /dev/null +++ b/example/client.c @@ -0,0 +1,116 @@ +/* This is a simple TCP client that connects to port 1234 and prints a list + * of files in a given directory. + * + * It directly deserializes and serializes messages from network, minimizing + * memory use. + * + * For flexibility, this example is implemented using posix api. + * In a real embedded system you would typically use some other kind of + * a communication and filesystem layer. + */ + +#include <sys/socket.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <unistd.h> +#include <dirent.h> +#include <stdio.h> +#include <string.h> + +#include <pb_encode.h> +#include <pb_decode.h> + +#include "fileproto.h" +#include "common.h" + +bool printfile_callback(pb_istream_t *stream, const pb_field_t *field, void *arg) +{ + FileInfo fileinfo; + + if (!pb_decode(stream, FileInfo_fields, &fileinfo)) + return false; + + printf("%-10lld %s\n", fileinfo.inode, fileinfo.name); + + return true; +} + +bool listdir(int fd, char *path) +{ + ListFilesRequest request; + ListFilesResponse response; + pb_istream_t input = pb_istream_from_socket(fd); + pb_ostream_t output = pb_ostream_from_socket(fd); + uint8_t zero = 0; + + if (path == NULL) + { + request.has_path = false; + } + else + { + request.has_path = true; + if (strlen(path) + 1 > sizeof(request.path)) + { + fprintf(stderr, "Too long path.\n"); + return false; + } + + strcpy(request.path, path); + } + + if (!pb_encode(&output, ListFilesRequest_fields, &request)) + { + fprintf(stderr, "Encoding failed.\n"); + return false; + } + + /* We signal the end of request with a 0 tag. */ + pb_write(&output, &zero, 1); + + response.file.funcs.decode = &printfile_callback; + + if (!pb_decode(&input, ListFilesResponse_fields, &response)) + { + fprintf(stderr, "Decoding failed.\n"); + return false; + } + + if (response.path_error) + { + fprintf(stderr, "Server reported error.\n"); + return false; + } + + return true; +} + +int main(int argc, char **argv) +{ + int sockfd; + struct sockaddr_in servaddr; + char *path = NULL; + + if (argc > 1) + path = argv[1]; + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + + memset(&servaddr, 0, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + servaddr.sin_port = htons(1234); + + if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) + { + perror("connect"); + return 1; + } + + if (!listdir(sockfd, path)) + return 2; + + close(sockfd); + + return 0; +} |