Advertisement
milanmetal

[C] Client & Server TCP/IP

Mar 13th, 2018
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.34 KB | None | 0 0
  1. /************ Client.c *************/
  2.  
  3. /*
  4. Send a file over a socket.
  5.  
  6. Interface:
  7.  
  8.     ./executable [<input_path> [<sever_hostname> [<port>]]]
  9.  
  10. Defaults:
  11.  
  12. - input_path: input.tmp
  13. - server_hostname: 127.0.0.1
  14. - port: 12345
  15. */
  16.  
  17. #define _XOPEN_SOURCE 700
  18.  
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21.  
  22. #include <arpa/inet.h>
  23. #include <fcntl.h>
  24. #include <netdb.h> /* getprotobyname */
  25. #include <netinet/in.h>
  26. #include <sys/stat.h>
  27. #include <sys/socket.h>
  28. #include <unistd.h>
  29.  
  30. int main(int argc, char **argv) {
  31.     char protoname[] = "tcp";
  32.     struct protoent *protoent;
  33.     char *file_path = "input.tmp";
  34.     char *server_hostname = "127.0.0.1";
  35.     char *server_reply = NULL;
  36.     char *user_input = NULL;
  37.     char buffer[BUFSIZ];
  38.     in_addr_t in_addr;
  39.     in_addr_t server_addr;
  40.     int filefd;
  41.     int sockfd;
  42.     ssize_t i;
  43.     ssize_t read_return;
  44.     struct hostent *hostent;
  45.     struct sockaddr_in sockaddr_in;
  46.     unsigned short server_port = 12345;
  47.  
  48.     if (argc > 1) {
  49.         file_path = argv[1];
  50.         if (argc > 2) {
  51.             server_hostname = argv[2];
  52.             if (argc > 3) {
  53.                 server_port = strtol(argv[3], NULL, 10);
  54.             }
  55.         }
  56.     }
  57.  
  58.     filefd = open(file_path, O_RDONLY);
  59.     if (filefd == -1) {
  60.         perror("open");
  61.         exit(EXIT_FAILURE);
  62.     }
  63.  
  64.     /* Get socket. */
  65.     protoent = getprotobyname(protoname);
  66.     if (protoent == NULL) {
  67.         perror("getprotobyname");
  68.         exit(EXIT_FAILURE);
  69.     }
  70.     sockfd = socket(AF_INET, SOCK_STREAM, protoent->p_proto);
  71.     if (sockfd == -1) {
  72.         perror("socket");
  73.         exit(EXIT_FAILURE);
  74.     }
  75.     /* Prepare sockaddr_in. */
  76.     hostent = gethostbyname(server_hostname);
  77.     if (hostent == NULL) {
  78.         fprintf(stderr, "error: gethostbyname(\"%s\")\n", server_hostname);
  79.         exit(EXIT_FAILURE);
  80.     }
  81.     in_addr = inet_addr(inet_ntoa(*(struct in_addr*)*(hostent->h_addr_list)));
  82.     if (in_addr == (in_addr_t)-1) {
  83.         fprintf(stderr, "error: inet_addr(\"%s\")\n", *(hostent->h_addr_list));
  84.         exit(EXIT_FAILURE);
  85.     }
  86.     sockaddr_in.sin_addr.s_addr = in_addr;
  87.     sockaddr_in.sin_family = AF_INET;
  88.     sockaddr_in.sin_port = htons(server_port);
  89.     /* Do the actual connection. */
  90.     if (connect(sockfd, (struct sockaddr*)&sockaddr_in, sizeof(sockaddr_in)) == -1) {
  91.         perror("connect");
  92.         return EXIT_FAILURE;
  93.     }
  94.  
  95.     while (1) {
  96.         read_return = read(filefd, buffer, BUFSIZ);
  97.         if (read_return == 0)
  98.             break;
  99.         if (read_return == -1) {
  100.             perror("read");
  101.             exit(EXIT_FAILURE);
  102.         }
  103.         /* TODO use write loop: https://stackoverflow.com/questions/24259640/writing-a-full-buffer-using-write-system-call */
  104.         if (write(sockfd, buffer, read_return) == -1) {
  105.             perror("write");
  106.             exit(EXIT_FAILURE);
  107.         }
  108.     }
  109.     free(user_input);
  110.     free(server_reply);
  111.     close(filefd);
  112.     exit(EXIT_SUCCESS);
  113. }
  114.  
  115. /************ Server.c *************/
  116. // https://stackoverflow.com/questions/2014033/send-and-receive-a-file-in-socket-programming-in-linux-with-c-c-gcc-g
  117. // https://stackoverflow.com/questions/2014033/send-and-receive-a-file-in-socket-programming-in-linux-with-c-c-gcc-g
  118. // https://stackoverflow.com/questions/2014033/send-and-receive-a-file-in-socket-programming-in-linux-with-c-c-gcc-g
  119.  
  120. /*
  121. Receive a file over a socket.
  122.  
  123. Saves it to output.tmp by default.
  124.  
  125. Interface:
  126.  
  127.     ./executable [<output_file> [<port>]]
  128.  
  129. Defaults:
  130.  
  131. - output_file: output.tmp
  132. - port: 12345
  133. */
  134.  
  135. #define _XOPEN_SOURCE 700
  136.  
  137. #include <stdio.h>
  138. #include <stdlib.h>
  139.  
  140. #include <arpa/inet.h>
  141. #include <fcntl.h>
  142. #include <netdb.h> /* getprotobyname */
  143. #include <netinet/in.h>
  144. #include <sys/stat.h>
  145. #include <sys/socket.h>
  146. #include <unistd.h>
  147.  
  148. int main(int argc, char **argv) {
  149.     char *file_path = "output.tmp";
  150.     char buffer[BUFSIZ];
  151.     char protoname[] = "tcp";
  152.     int client_sockfd;
  153.     int enable = 1;
  154.     int filefd;
  155.     int i;
  156.     int server_sockfd;
  157.     socklen_t client_len;
  158.     ssize_t read_return;
  159.     struct protoent *protoent;
  160.     struct sockaddr_in client_address, server_address;
  161.     unsigned short server_port = 12345u;
  162.  
  163.     if (argc > 1) {
  164.         file_path = argv[1];
  165.         if (argc > 2) {
  166.             server_port = strtol(argv[2], NULL, 10);
  167.         }
  168.     }
  169.  
  170.     /* Create a socket and listen to it.. */
  171.     protoent = getprotobyname(protoname);
  172.     if (protoent == NULL) {
  173.         perror("getprotobyname");
  174.         exit(EXIT_FAILURE);
  175.     }
  176.     server_sockfd = socket(
  177.         AF_INET,
  178.         SOCK_STREAM,
  179.         protoent->p_proto
  180.     );
  181.     if (server_sockfd == -1) {
  182.         perror("socket");
  183.         exit(EXIT_FAILURE);
  184.     }
  185.     if (setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable)) < 0) {
  186.         perror("setsockopt(SO_REUSEADDR) failed");
  187.         exit(EXIT_FAILURE);
  188.     }
  189.     server_address.sin_family = AF_INET;
  190.     server_address.sin_addr.s_addr = htonl(INADDR_ANY);
  191.     server_address.sin_port = htons(server_port);
  192.     if (bind(
  193.             server_sockfd,
  194.             (struct sockaddr*)&server_address,
  195.             sizeof(server_address)
  196.         ) == -1
  197.     ) {
  198.         perror("bind");
  199.         exit(EXIT_FAILURE);
  200.     }
  201.     if (listen(server_sockfd, 5) == -1) {
  202.         perror("listen");
  203.         exit(EXIT_FAILURE);
  204.     }
  205.     fprintf(stderr, "listening on port %d\n", server_port);
  206.  
  207.     while (1) {
  208.         client_len = sizeof(client_address);
  209.         puts("waiting for client");
  210.         client_sockfd = accept(
  211.             server_sockfd,
  212.             (struct sockaddr*)&client_address,
  213.             &client_len
  214.         );
  215.         filefd = open(file_path,
  216.                 O_WRONLY | O_CREAT | O_TRUNC,
  217.                 S_IRUSR | S_IWUSR);
  218.         if (filefd == -1) {
  219.             perror("open");
  220.             exit(EXIT_FAILURE);
  221.         }
  222.         do {
  223.             read_return = read(client_sockfd, buffer, BUFSIZ);
  224.             if (read_return == -1) {
  225.                 perror("read");
  226.                 exit(EXIT_FAILURE);
  227.             }
  228.             if (write(filefd, buffer, read_return) == -1) {
  229.                 perror("write");
  230.                 exit(EXIT_FAILURE);
  231.             }
  232.         } while (read_return > 0);
  233.         close(filefd);
  234.         close(client_sockfd);
  235.     }
  236.     return EXIT_SUCCESS;
  237. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement